ARM的数据处理指令不涉及任何内存访问,需要专门的内存访问指令(memory access instructions)来读取内存或写入内存。
加载寄存器或存储寄存器,32位字或8位无符号字节。字节加载是zero-extended到32位。
语法:
有4种形式:
zero offset
pre-indexed offset
program-relative
post-indexed offset
对应的语法:
op{cond}{B}{T} Rd, [Rn]
op{cond}{B} Rd, [Rn, FlexOffset]{!}
op{cond}{B} Rd, label
op{cond}{B}{T} Rd, [Rn], FlexOffset
op, LDR(load register)或者STR(store register)
B, 只传送最低位的字节。如果是加载,Rd的其它字节清0.
T, 在用户模式下访问,即使处于特权模式。T不能用在pre-indexed模式。
Rn, 内存地址寄存器,下列情况下,Rn和Rd不能是同一个寄存器,1 pre-indexed包括写回。2 post-indexed。3 使用T后缀。
FlexOffset,一个灵活的偏移,见后面。
label,一个程序相对表达式,范围+/-4KB
!,可选的后缀,如果有,包含偏移的地址写回到Rn。
使用Rn作为地址。
传送之前先计算偏移,并按照计算偏移后的地址来传送,如果使用!后缀,则传送地址写回到Rn。如果使用写回,则Rn不能位r15.
这个和不带!后缀的pre-indexed是一样的,由汇编器帮你计算相对于PC的偏移。产生一个pre-indexed指令,使用PC作为Rn。
先使用Rn作为内存传送地址,数据传送完成后,再将应用偏移后的地址赋给Rn。由于地址被写回,Rn不能使用r15.
有两种形式
#expr
{-}Rm{, shift}
LDR,支持有符号8位,有符号16位,无符号16位。
STR,支持16位无符号halfword。
有符号加载是sign-extended 32位,无符号加载是zero-extended到32位。
语法
op{cond}{type} Rd, [Rn]
op{cond}{type} Rd, [Rn, FlexOffset]{!}
op{cond}{type} Rd, label
op{cond}{type} Rd, [Rn], FlexOffset
type
SH 有符号halfword,只支持LDR
H 无符号halfword
SB 有符号字节,只支持LDR
支持批量传送,任何r0-r15寄存器的组合。
语法:
op{cond}addr_mode Rn{!}, reglist{^}
addr_mode
IA 传送后增加地址。
IB 传送前增加地址。
DA 传送后减小地址。
DB 传送后减小地址。
FD full descending stack
ED empty descending stack
FA full ascending stack
EA empty ascending stack
Rn 基寄存器,包含传送的地址,Rn不能位r15。
! 可选的后缀,如果有,最后一个地址被写回到Rn。
^ 可选的后缀,不能用在用户模式或系统模式。
- 如果op是LDM,且包含pc,则会将SPSR拷贝到CPSR,用于从异常处理中返回。
- 其它的,使用用户模式的寄存器,而不是当前bank的寄存器。
FD
= Full Descending
STMFD
/LDMFD
= STMDB
/LDMIA
ED
= Empty Descending
STMED
/LDMED
= STMDA
/LDMIB
FA
= Full Ascending
STMFA
/LDMFA
= STMIB
/LDMDA
EA
= Empty Ascending
STMEA
/LDMEA
= STMIA
/LDMDB
参考
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0231b/Chddgiff.html