推和弹出手臂

时间:2014-11-23 22:25:33

标签: assembly arm

我不太了解堆栈命令或堆栈的工作原理。

说我有没有

PUSH R3
POP R3

第1行:这是否意味着R3的内容将被置于堆栈的顶部?如果R3改变了,那么堆栈的内容会改变吗?

第2行:在第二行,堆栈顶部的内容是否会从堆栈移动到R3中,或者是被压入堆栈的R3中的内容从堆栈弹出?

当寄存器被括在括号中时,pop / push会做什么

POP {LR}

2 个答案:

答案 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

括号被称为&#34;注册列表&#34;在手臂组装表示法中。 GNU GAS 2.26.1 接受pushpop指令而没有大括号,即使是单{} push r1推送push。< / p>

另请注意: