程序集多次推送不考虑推送列表顺序

KDX*_*DX2 3 assembly stack arm

我有3个参数,我将它们存储在三个不同的寄存器中,比如R1,R8和R9.我发现,一旦多次推送完成PUSH {r1,r8 ... etc},我在内存中找到的内容与写PUSH {r9,r8,R1}时完全相同.

这些值确实不同,R9保持1000,r1和r8都低于50.为什么它们不按我在指令中写的顺序推?

实际上,即使我接受r8,r9,r1的顺序,它也会将它们再次存储在堆栈中,如r9,r8,r1从下到上.

我以为PUSH {r1,r8,r9}不会一样PUSH {r9,r8,r1}.

Col*_*lin 8

你没有说你正在使用什么处理器,但程序集看起来像某种描述的ARM.

正如ARM-Push中所述

PUSH和POP是STMDB和LDM(或LDMIA)的同义词,具有基址寄存器sp(r13),并且调整后的地址写回基址寄存器.在这些情况下,PUSH和POP是首选的助记符. 寄存器按数字顺序存储在堆栈中,最低编号的寄存器位于最低地址

如果由于某种原因,您确实需要在堆栈上以特定顺序存储内容,则必须使用多个指令.

为什么是案件问题.正如Peter Cordes在评论中所说,这是由于寄存器列表被存储为指令中的位域.从ARM ARM(ARM体系结构参考手册)中可以看出LDM/STM指令的编码

Bit 31 -- 28 27 26 25 24 23 22 21 20 19 -- 16 15 -------- 0
     COND     1  0  0  P  U  S  W  L    Rn      Registers
Run Code Online (Sandbox Code Playgroud)

由此可以清楚地看到,存储r0,r8和r9将设置位0,8和9(指令的低16位中的0x0301),而不管它们在代码中写入的顺序如何.

  • 它存储您传递的列表中编号最小的寄存器,而不管最低地址列表的顺序如何.因此,如果你有一个递减的堆栈(事物被推入较低的地址),r0将位于顶部,然后是r8,然后是r9.这就是你所看到的.如果它们必须按照你指定的顺序然后是`PUSH r0`然后是'PUSH r8`然后是'PUSH r9` (3认同)