LDR
和STR
是两个主要的内存访问指令。
LDR
指令从内存加载数据到寄存器。
LDR<c><q> <Rt>, [<Rn> {, #+/-<imm>}]
LDR<c><q> <Rt>, [<Rn>, #+/-<imm>]!
LDR<c><q> <Rt>, [<Rn>], #+/-<imm>
LDR<c><q> <Rt>, <label>
LDR<c><q> <Rt>, [<Rn>, <Rm> {, LSL #<shift>}]
STR
指令从寄存器存储数据到内存。
STR<c><q> <Rt>, [<Rn> {, #+/-<imm>}]
STR<c><q> <Rt>, [<Rn>, #+/-<imm>]!
STR<c><q> <Rt>, [<Rn>], #+/-<imm>
STR<c><q> <Rt>, [<Rn>, <Rm> {, LSL #<shift>}]
对于内存访问指令,下列寻址方式是可用的:
偏移寻址(Offset Addressing):[<Rn>,<offset>]
从基址寄存器Rn获取的基址值加或减去偏移量所得的结果作为内存访问的地址。基址寄存器始终没有被改变。
伪代码表示:
addr=Rn+offset
visit(memory[addr])
先变址寻址(Pre-indexed Addressing):[<Rn>,<offset>]!
从基址寄存器Rn获取的基址值加或减去偏移量所得的结果作为内存访问的地址。之后此地址被写回基址寄存器。
伪代码表示:
addr=Rn+offset
visit(memory[addr])
Rn=addr
后变址寻址(Post-indexed Addressing):[<Rn>],offset
内存访问的地址就是基址寄存器Rn的值,之后再对Rn加或减去偏移量并回写进寄存器。
伪代码表示:
visit(memory[Rn])
addr=Rn+offset
Rn=addr
其中,<Rn>
是基址寄存器。<offset>
字段可以是如下形式:
- 立即数,形如
<imm8>
或<imm12>
- 下标寄存器(index register),形如
<Rm>
- 进行偏移的下标寄存器(shifted index register),形如
<Rm>, LSL #<shift>
下面是几个例子:
指令 | 解释 |
---|---|
str r2, [r1, #2] |
memory[r1+2]=r2; |
str r2, [r1, #4]! |
addr=r1+4; memory[addr]=r2; r1=addr; |
ldr r3, [r1], #4 |
r3=memory[r1]; r1=r1+4; |
str r2, [r1, r2] |
memory[r1+r2]=r2; |
str r2, [r1, r2]! |
addr=r1+r2; memory[addr]=r2; r1=addr; |
ldr r3, [r1], r2 |
r3=memory[r1]; r1=r1+r2; |
str r2, [r1, r2, LSL#2] |
memory[r1+(r2<<2)]=r2; |
str r2, [r1, r2, LSL#2]! |
addr=r1+(r2<<2); memory[addr]=r2; r1=addr; |
ldr r3, [r1], r2, LSL#2 |
r3=memory[r1]; r1=r1+(r2<<2); |