从堆栈中复制一个字节而不更改堆栈指针(Motorolla 68000)?

Copy a byte from a stack without changing the stack pointer(Motorolla 68000)?

有人问我以下问题:

Three  bytes  are  pushed  onto  the  runtime  stack.  Copy  the  third  
byte  from  the  runtime  stack  to D0 without changing the stack pointer

所以我有一个看起来像这样的堆栈:

|   |
|   |
|cc | <-- SP points to cc
|bb |
|aa |

我不确定如何将 cc 的值复制到寄存器 D0 中。我知道我可以像这样将它从堆栈中弹出... MOVE.B (SP)+,D0,但这会将堆栈指针更改为指向 bb

此外,用户堆栈和 运行 时间堆栈之间有什么区别? 例如,如果我被要求从用户堆栈 (A6) 中弹出一个字节,然后将其推入 运行 时间堆栈,我该怎么做? 有什么想法吗?

您需要在堆栈指针上使用偏移量。还要记住堆栈向后(通常 :) )所以

move.b (sp), d0

在你的例子中会产生 $cc

move.b 2(sp), d0

会让你 $aa 进入 d0

希望对您有所帮助

这是一个棘手的问题,如果不知道字节是通过什么方式进入堆栈的,则无法回答,特别是因为在 An=A7=SP 时使用具有预递减 -(An) 模式的地址寄存器时存在一个奇怪的问题.例如,如果像这样推送字节:

move.b #$aa,-(sp)
move.b #$bb,-(sp)
move.b #$cc,-(sp)

|$??| +5
|$aa| +4
|$??| +3
|$bb| +2
|$??| +1
|$cc| <--- SP points here

每次移动堆栈指针减少两个。 68k 对此的处理方式与其他地址寄存器不同,因为奇堆栈指针地址会在下一次尝试压入一个字或长字(通过子程序调用显式或隐式)时触发地址异常(至少对于 MC68000),原因是a word/long 访问一个奇数地址。这记录在系列参考手册第 2-7 页中:http://www.freescale.com/files/archives/doc/ref_manual/M68000PRM.pdf

如果这 3 个字节是更大实体的一部分,例如一个长字,它们将被放置在连续的地址上:

move.l #$ccbbaa??,-(sp)

|$??| +3
|$aa| +2
|$bb| +1
|$cc| <--- SP points here

因此,如果将它们作为字节推送,则答案类似于 "move.b 4(sp),d0",但如果它们是更大实体的一部分,则答案类似于 "move.b 2(sp),d0"。