LDM 指令,STM 指令
LDM 指令,STM 指令
(LDM|STM)<cond> [<addressing_mode>] <Rn>[!], ({<Rn>[,<Rn>]}|{<Rn>-<Rn>})
例如
LDMIA R0, {R1, R2, R3}
LDMIA R0, {R1-R3}
LDMIA R0!, {R1-R3} # ! 表示最后那个寄存器的值会改变
- 多寄存器加载存储指令
格式 | 地址变化方式 | 操作寄存器的方向 |
---|---|---|
IA(Increment After) | 先存储后增长 | –> |
IB(Increment Before) | 先增长后存储 | –> |
DA(Decrement After) | 先存储后递减 | <– |
DB(Decrement Before) | 先递减后存储 | <– |
地址改变的时机只与 A,B 有关。
地址改变的方向与 I,D 有关,与 LDM,STM 无关。
操作寄存器方向上的不同,刚好让内存顺序和寄存器顺序对应匹配起来了。
- 堆栈寻址方式
格式 | 地址变化方式 | 操作寄存器的方向 |
---|---|---|
EA | 空栈递增(先存取后改变地址) | –> |
FA | 满栈递增(先改变地址后存取) | –> |
ED | 空栈递减(先存取后改变地址) | <– |
FD | 满栈递减(先改变地址后存取) | <– |
地址改变的时机只与 E,F 有关。
地址改变的方向不仅 与 A,D 有关, 还与 LDM,STM 有关。A 本意是递增,但只有在和 STM 搭配时才是本意。也就是说 STMFA 地址是递增,而 LDMFA 地址是递减的。看似奇怪,换个角度看, FA 是对一个栈的描述。对于同一个栈,压栈和出栈的地址改变顺序必然是相反的。这里仅用了压栈(STM)的顺序来代表这个栈,所以对于出栈(LDM)方向就相反了。
操作寄存器的方向的不同,也是刚好让内存顺序和寄存器顺序对应匹配起来了。
- 总结
对于LDM 指令,STM 指令,无非就是关系三个指标——什么时候改变地址、往哪个方向改变地址、先操作哪个寄存器。什么时候改变地址,先操作哪个寄存器是相对容易的,复杂在地址改变的方向。判断地址改变方向分两种情况,一种是只看 I,D,一种是通过压栈的方向 A,D 确定一个栈,在这个栈的基础上判断 LDM,STM 的方向。
参考资料
- yang_qin224. ARM 汇编指令. 2019-06-20 07:42:06.
- 何有飞. LDMIA、LDMIB、LDMDB、LDMDA、STMIA、LDMFD、LDMFA、LDMED、LDMEA等指令详解. 2019-06-20 08:43:20.