我不太了解堆栈命令或堆栈的工作原理。
说我有没有
PUSH R3
POP R3
第1行:这是否意味着R3的内容将被置于堆栈的顶部?如果R3改变了,那么堆栈的内容会改变吗?
第2行:在第二行,堆栈顶部的内容是否会从堆栈移动到R3中,或者是被压入堆栈的R3中的内容从堆栈弹出?
当寄存器被括在括号中时,pop / push会做什么
POP {LR}
答案 0 :(得分:11)
上述堆栈操作只是地址部分中使用sp
的内存操作的快捷方式。 E.g。
PUSH {r3}
POP {r3}
是
的别名str r3, [sp, #-4]!
ldr r3, [sp], #4
第一个操作说"将r3
的内容存储到[sp - #4]
并将sp
减少4"。最后一个"从r3
加载[sp]
并将sp
增加4"。
代替{r3}
,您可以使用任何其他寄存器或寄存器集(例如{r1,r2,r3,lr}
。寄存器集在机器代码的位掩码中指定,因此您不能影响寄存器的顺序存储/加载。
答案 1 :(得分:3)
最小的armv7示例
最好的学习方法是编写最少的示例,在仿真器上运行它们,并观察GDB上所有寄存器的内容:
/* Save sp before push. */
mov r0, sp
/* Push. */
mov r1, #1
mov r2, #2
push {r1, r2}
/* Save sp after push. */
mov r1, sp
/* Restore. */
mov r3, #0
mov r4, #0
pop {r3, r4}
cmp r3, #1
bne fail
cmp r4, #2
bne fail
/* Check that stack pointer moved down by 8 bytes
* (2 registers x 4 bytes each). */
sub r0, r1
cmp r0, #8
bne fail
在Ubuntu 18.04上运行示例的Boilerplate:https://github.com/cirosantilli/arm-assembly-cheat/blob/f8d78775bd052e9ead579a408c0a2a1651adb9f0/v7/push.S
括号被称为"注册列表"在手臂组装表示法中。 GNU GAS 2.26.1 不接受push
和pop
指令而没有大括号,即使是单{}
push r1
推送push
。< / p>
另请注意:
pop
和stp
,编制者经常使用ldp
和list = ["2016-08-02T09:20:32.456Z", "2016-07-03T09:22:35.129Z"]
。示例:https://github.com/cirosantilli/arm-assembly-cheat/blob/f8d78775bd052e9ead579a408c0a2a1651adb9f0/v8/common_arch.h#L20