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

时间:2015-12-01 00:56:03

标签: assembly compilation stack motorola 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),然后将其推入运行时堆栈,我该怎么做? 有什么想法吗?

2 个答案:

答案 0 :(得分:3)

这是一个棘手的问题,如果不知道字节到达堆栈的方式是不可回答的,特别是因为当使用地址寄存器和precrement - (An)模式时An = A7 = SP时存在奇怪现象。例如,如果像这样按下字节:

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

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

每次移动时,堆栈指针减少 2 。 68k与其他地址寄存器的区别对待是因为奇数堆栈指针地址会在下次尝试推送一个字或长字(由子程序调用显式或隐式)时触发地址异常(对于MC68000至少)奇数地址上的字/长访问。这在第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

所以答案就像&#34; move.b 4(sp),d0&#34;如果它们被推送为字节,但是&#34; move.b 2(sp),d0&#34;如果他们是更大实体的一部分。

答案 1 :(得分:2)

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

move.b (sp), d0

会在你的例子中产生$ cc

move.b 2(sp), d0

将获得$ aa到d0

希望有所帮助