PUSH 和 POP 括号中寄存器的排序

Ordering of registers in PUSH and POP brackets

ARM documentation 对 PUSH 和 POP 表示以下内容

PUSH stores registers on the stack, with the lowest numbered register using the lowest memory address and the highest numbered register using the highest memory address.

POP loads registers from the stack, with the lowest numbered register using the lowest memory address and the highest numbered register using the highest memory address.

我发现 tutorial 说的是这个

...the registers in the {} can be specified in any order, but the order in which they appear on the stack is fixed...

所以根据上面的解释,一个PUSH括号中寄存器的顺序是没有关系的。 IE。 PUSH {R0,R1,R2}PUSH {R2,R1,R0}PUSH {R1,R2,R0} 都会导致堆栈中的某些排序,因为 "...lowest/highest 编号的寄存器(R0/R2) 使用 lowest/highest(堆栈)内存地址...".

如果您查看汇编的 hex/binary,您会发现 push 具有相同的寄存器但不同的顺序编码为相同的指令。这将与指令编码有关,因为它几乎是寄存器的位掩码(参见 How are encoded register operands in ARM assembler ?

你很接近,你需要始终获得 TRM(内核、cortex-m3、cortex-m0 等的技术参考手册)和 ARM(该内核 armv6 指定的体系结构的体系结构参考手册- m, armv7-m, armv8-m)

.thumb

push {r0,r1,r2}
push {r2,r1,r0}
push {r0}
push {r1}
push {r2}

Disassembly of section .text:

00000000 <.text>:
   0:   b407        push    {r0, r1, r2}
   2:   b407        push    {r0, r1, r2}
   4:   b401        push    {r0}
   6:   b402        push    {r1}
   8:   b404        push    {r2}

从ARM ARM可以看到push指令的低8位是一个寄存器list/mask。所以 r0 是位 0,r1 是位 1,依此类推。所以b407中的7表示r0,r1,r2这三个寄存器。逻辑在机器代码而不是汇编语言上运行,如果设置,机器代码从位 0 到位 7,然后压入该寄存器。汇编程序所做的只是创建机器代码,它不会创建额外的指令或类似的东西。

如果您希望它们以不同的顺序排列,则必须用汇编语言将它们编写成单独的指令。

逻辑获取列表中启用的寄存器总数,获取堆栈指针,减去 4 寄存器,然后从该地址开始按列表中的寄存器顺序写入。然后将堆栈指针本身向下调整 4 个寄存器。这在ARM ARM 中都有记载。因此,请继续阅读,您会找到问题的答案。