带有直接偏移量、前变直接偏移量或后边直接偏移量的加载和存储。
- 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地址不变