ARM汇编的LDM和STM指令
批量加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据.LDM 为加载多个寄存器,STM 为存储多个寄存器.允许一条指令传送 16 个寄存器的任何子集或所有寄存器.指令格式如下:
LDM{cond}<模式> Rn{!},reglist{^}
STM{cond}<模式> Rn{!},reglist{^}
LDM /STM 的主要用途是现场保护、数据复制、参数传送等。其模式有 8 种,如下:(前面 4 种用于数据块的传输,后面 4 种是堆栈操作)
- IA:每次传送后地址加 4
- IB:每次传送前地址加 4
- DA:每次传送后地址减 4
- DB:每次传送前地址减 4
- FD:满递减堆栈
- ED:空递增堆栈
- FA:满递增堆栈
- EA:空递增堆栈
其中,寄存器Rn为基址寄存器,装有传送数据的初始地址,Rn不允许为R15;后缀“!”表示最后的地址写回到Rn中;寄存器列表reglist可包含多于一个寄存器或寄存器范围,使用“,”分开,如{R1,R2,R6-R9},寄存器排列由小到大排列;“^”后缀不允许在用户模式呈系统模式下使用,若在 LDM 指令用寄存器列表中包含有 PC 时使用,那么除了正常的多寄存器传送外,将 SPSR 拷贝到 CPSR 中,这可用于异常处理返回;使用“^”后缀进行数据传送且寄存器列表不包含 PC 时,加载/存储的是用户模式的寄存器,而不是当前模式的寄存器。
LDMIA R0!,{R3-R9} ;加载 R0 指向的地址上的多字数据,保存到 R3~R9 中,R0 值更新
STMIA R1!,{R3-R9} ;将 R3~R9 的数据存储到 R1 指向的地址上,R1 值更新
STMFD SP!,{R0-R7,LR} ;现场保存,将 R0~R7、LR 入栈
LDMFD SP!,{R0-R7,PC}^;恢复现场,异常处理返回
在进行数据复制时,先设置好源数据指针,然后使用块拷贝寻址指令 LDMIA/STMIA、
LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB 进行读取和存储。而进行堆栈操作时,则要
先设置堆栈指针,一般使用 SP 然后使用堆栈寻址指令 STMFD/LDMFD、STMED。LDMED、
STMFA/LDMFA、STMEA/LDMEA 实现堆栈操作。
多寄存器传送指令示意图如图所示,其中R1为指令执行前的基址寄存器,R1则为指
令执行完后的基址寄存器.