带有直接偏移量、前变直接偏移量或后边直接偏移量的加载和存储。
op{type}{cond} Rt, [Rn {, #offset}] ;立即偏移
op{type}{cond} Rt, [Rn, #offset]! ;前索引
op{type}{cond} Rt, [Rn], #offset ;后索引
op{type}{cond} Rt, Rt2, [Rn {, #offset}] ;双字立即偏移
op{type}{cond} Rt, Rt2, [Rn, #offset]! ;双字前索引
op{type}{cond} Rt, Rt2, [Rn], #offset ;双字后索引
其中:
op 是下列项之一:
LDR 加载寄存器。
STR 存储寄存器。
type 是下列项之一:
B 无符号字节(加载时零扩展为 32 位。)
SB 有符号字节(仅 LDR。符号扩展为 32 位。)
H 无符号半字(加载时零扩展为 32 位。)
SH 有符号半字(仅 LDR。符号扩展为 32 位。)
- 如果是字,则省略。
cond 是一个可选的条件代码(请参阅条件执行)。
Rt 要加载或存储的寄存器。
Rn 内存地址所基于的寄存器。
offset 是偏移量。如果省略了 offset,则该地址为 Rn 中的地址。
Rt2 为附加寄存器,在双字运算中使用,用于加载或存储。
;实例 功能描述
; ldr: load register
.equ label, 0x80002000
ldr r0, label ;从地址label读取一个字到r0
ldr r0, =label ;把label这个“立即数”加载到r0
ldr r1, r0 ;从地址r0读取数据到r1中
ldr r2, [r0, #offset] ;从地址r0+offset处读取一个字到r2
ldrb r2, [r0, #offset] ;从地址r0+offset处读取一个字节到r2
ldrh r2, [r0, #offset] ;从地址r0+offset处读取一个半字到r2
LDRD r0, r1, [r2, #offset] ;从地址r2+offset处读取双字(64位)到
;r0(低32位)和r1(高32位)
;前索引
ldr r1, [r0, #offset]! ;从地址r0+offset处读取一个字到r1,然后r0=r0+offset
;如果没有! 那么最后r0的值得不到更新
ldrd r1, r2, [r0, #offset]! ;从r0+offset地址读取64位数据到r1(低32位)和r2(高32位)
;然后r0=r0+offset
;后索引
ldr r1, [r0], #offset ;从r0地址获取一个字加载到r1,然后r0=r0+offset
ldrd r1, r2, [r0], #offset ;从r0地址获取一个双字加载到r1, r2,然后r0=r0+offset
; str store register
str r0, label ;从r0读取一个字到地址label中
str r0, =label ;把r0值更新label这个“立即数”
str r1, r0 ;从地址r1读取数据到r0中
str r2, [r0, #offset] ;从地址r2处读取一个字到r0+offset
strb r2, [r0, #offset] ;从地址r2处读取一个低字节到r0+offset
strh r2, [r0, #offset] ;从地址r2处读取一个低半字到r0+offset
STRD r0, r1, [r2, #offset] ;从地址r0(低32位)和r1(高32位)处
;读取双字到r2+offset
;前索引
str r1, [r0, #offset]! ;从地址r1处读取一个字到r0+offset,然后r0=r0+offset
;如果没有! 那么最后r0的值得不到更新
strd r1, r2, [r0, #offset]! ;从r1(低32位)和r2(高32位)地址读取64位数据到r0+offset
;然后r0=r0+offset
;后索引
str r1, [r0], #offset ;从r1地址获取一个字加载到r0,然后r0=r0+offset
strd r1, r2, [r0], #offset ;从r1, r2地址获取一个双字加载到r0,然后r0=r0+offset
加载、存储多个寄存器,可以使用r0-r15任何寄存器组合进行传输。
op{addr_mode}{cond} Rn{!}, reglist{^}
其中:
op 指令
LDM load multiple registers 加载多个寄存器
STM store multiple registers 存储多个寄存器
addr_mode 模式
IA increment address after each transfer 先传输后地址自增
IB increment address before each transfer 先地址自增后传输
DA decrement address after each transfer 先传输后地址自减
DB decrement address before each transfer 先地址自减后传输
FD full descending stack 满栈递增,地址从当前sp开始
ED empty descending stack 空栈递增,地址从sp+4开始取数据
FA full ascending stack 满栈递减
EA empty ascending stack. 空栈递减
cond 是一个可选的条件代码(请参阅第2-17 页的条件执行)。
Rn 是基址寄存器,存储有用于传送初始地址的 ARM 寄存器。Rn 不能 为 r15。
! 是一个可选的后缀。如果有 ! ,则最终地址将写回到 Rn 中。
reglist 是一个或多个要加载或存储的寄存器列表,括在大括号内。
可包含 寄存器范围。如果包含多个寄存器或寄存器范围,
则必须用逗号隔 开(请参阅第4-28 页的示例)。
请参阅第4-27 页的32 位 Thumb-2 指令中的 reglist 限制。
^ 为一个可选后缀,仅可用于 ARM 状态。不可在用户模式或系统模 式下使用。
ldmia sp!, {r0-r12,lr} ;1.加载sp数据到lr, 然后sp=sp+4; 2.加载sp数据到r12, 然后sp=sp+1;
; 以此类推,最后加载sp数据到r0,然后sp=sp+1
; Rn为sp时,等效于POP
ldmib sp!, {r0-r12,lr} ;1.先sp=sp+4,然后加载sp数据到lr; 2.先sp=sp+1, 然后加载sp数据到r12;
; 以此类推,最后,先sp=sp+1,然后加载sp数据到r0
ldmda sp!, {r0-r12,lr} ;先传输后sp增后 ;
ldmdb sp!, {r0-r12,lr} ;sp先自增后传输
stmia sp!, {r0-r12,lr} ;1.存储lr数据到sp,然后sp=sp+4; 2.存储r12数据到sp,然后sp=sp+1;
; 以此类推,最后 存储r0数据到sp,然后sp=sp+4
; Rn为sp时,等效于PUSH
stmib sp!, {r0-r12,lr} ;sp先自增后传输
stmda sp!, {r0-r12,lr} ;sp先传输后自减
stmdb sp!, {r0-r12,lr} ;sp先自减后传输
ldmia sp, {r0-r12,lr} ; sp 不带!时,传输完成后,sp地址不变