3

为什么传递的值0(SP)只能在 处访问4(SP)?例如,我需要将一个数字传递给printnby0(SP)而不是4(SP)(因为它在例程中使用),否则它将不起作用。我错过了什么?

MOVE #12,D0
MOVE D0,0(SP)   here I use 0 offset

PRINTN:
        MOVE 4(SP),D1   |and here 4. Shoudln't be the same?
        MOVE #3,D0
        TRAP #15
        RTS
4

2 回答 2

4

根据您的代码,我猜 PRINTN 是子例程(函数、过程等),它是使用 JSR 调用的。如果是这样,您应该注意 JSR 的功能:它

  • SP减4
  • 通过 SP 中的地址将返回地址(JSR 之后指令的开头)放入内存
  • 将子程序地址(来自 JSR 指令)放入 PC

因此,在它之后,您知道的所有超出 SP 的偏移量都应增加 4。而且,是的,0(SP) 中的值作为 4(SP) 从子程序访问,28(SP) 应以相同的方式替换32(SP),依此类推。RTS 则相反——它将 SP 增加 4。

而且,每次 PUSH 和 POP 都会改变它;如果您在堆栈上保存 2 个寄存器,则在这些 PUSH 之后,所有偏移量都会额外增加 8,直到执行相应的 POP。这很容易被编译器跟踪,但更难被人类跟踪;这就是为什么 x86 除了 SP 之外还发明了 BP 的另一个论点。

于 2013-12-22T07:37:25.660 回答
3

如果我们假设这PRINTN是您通过JSR/获得的子例程,BSR那么您的问题将通过以下操作描述得到回答JSR

SP – 4 → Sp; PC → (SP); Destination Address → PC

也就是说,返回地址现在位于堆栈顶部,而在 之前位于堆栈顶部的任何JSR内容现在都将位于4(SP),依此类推。

于 2013-12-22T07:36:48.433 回答