ARM 中的 PUSH 和 POP 顺序

问题描述 投票:0回答:3

我试图理解 ARM 汇编中函数的开始和结束:

PUSH {R0-R2, LR}
POP {R0-R2, PC}

在 IDA 中查看这段代码,这就是我的理解(假设 SP 是 0x100):

PUSH R0 ; sp = 0xFC
PUSH R1 ; sp = 0xF8
PUSH R2 ; sp = 0xF4
PUSH LR ; sp = 0xF0
POP R0 ; sp = 0xF4
POP R1 ; sp = 0xF8
POP R2 ; sp = 0xFC
POP PC ; sp = 0x100

看起来 PC 获得了 R0 的值,而它应该获得 LR 的值。
PC不应该得到LR的值吗?

arm stack
3个回答
9
投票

当您 PUSH 或 POP 一堆寄存器时,无论方向如何,它们总是以相同的相对位置进入内存。编号最低的寄存器存储在最低地址并从最低地址加载。所以在这个例子中,除了 LR->PC 之外,所有内容都将返回到原始寄存器。

换句话说,想象一下 PUSH 存储的是 {LR,R2,R1,R0}。

查看您最喜欢的 Arm 32 位处理器系列的用户指南/指令集参考; LDM 和 STM。


1
投票

寄存器列表中包含 PC 的 POP 指令是一条分支指令,指向要从堆栈中弹出的值。 所以对于

POP {R0, PC}  ~= MOV PC,R0    ; Except that R0 is on the stack


0
投票

我也有同样的疑问。看起来如果你同时推送一堆寄存器,例如

PUSH {R1-R4}
,当执行 POP 时,最低编号的寄存器始终会转到最低编号的目标寄存器(例如,
POP {R2-R5}
将 R1 加载到 R2、R2 加载到 R3 等)。大括号内的目标寄存器的顺序与没关系。 (即使有
POP {R2,R5,R3,R4}
,R1 仍然转到 R2,R2 转到 R3,依此类推)

© www.soinside.com 2019 - 2024. All rights reserved.