 
- UID
- 1029342
- 性别
- 男
|

•LDR和STR——字和无符号字节加载/存储指令
LDR指令用于从内存中读取单一字或字节数据存入寄存器中,STR指令用于将寄存器中的单一字或字节数据保存到内存。指令格式如下:
LDR{cond}{T} Rd,<地址> ;将指定地址上的字数据读入Rd
STR{cond}{T} Rd,<地址> ;将Rd中的字数据存入指定地址
LDR{cond}B{T} Rd,<地址> ;将指定地址上的字节数据读入Rd
STR{cond}B{T} Rd,<地址> ;将Rd中的字节数据存入指定地址
•LDR和STR——字和无符号字节加载/存储指令
LDR/STR指令寻址非常灵活,它由两部分组成,其中一部分为一个基址寄存器,可以为任一个通用寄存器;另一部分为一个地址偏移量。地址偏移量有以下3种格式:
立即数。立即数可以是一个无符号的数值。这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
如:LDR R1,[R0,#0x12] ;R1<-[R0+0x12]
寄存器。寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
如:LDR R1,[R0,R2] ; R1<-[R0+R2]
LDR R1,[R0,-R2] ; R1<-[R0-R2]
寄存器及移位常数。寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
如:LDR R1,[R0,R2,LSL #2]
多寄存器加载/存储指令格式如下: LDM{cond}<模式> Rn{!},reglist{^} ;
STM{cond}<模式> Rn{!},reglist{^} ;
多寄存器加载/存储指令格式如下:
LDM{cond}<模式> Rn{!},reglist{^} ;
STM{cond}<模式> Rn{!},reglist{^} ;
cond:指令执行的条件;
模式:控制地址的增长方式,一共有8种模式;
!:表示在操作结束后,将最后的地址写回Rn中;
reglist :表示寄存器列表,可以包含多个寄存器,它们使用“,”隔开,如{R1,R2,R6-R9},寄存器由小到大排列;
^:可选后缀。允许在用户模式或系统模式下使用。它有以下两个功能:
1)若op是LDM且寄存器列表包含R15时,那么除了正常的多寄存器传送外,还将SPSR也复制到CPSR中。这用于异常处理返回,仅在异常模式下使用。
2)数据传入或传出的是用户模式下的寄存器,而不是当前模式的寄存器。
 多寄存器加载/存储指令的8种模式如下表所示,右边四种为堆栈操作、左边四种为数据传送操作。
模式
| 说明
| 模式
| 说明
| IA
| 每次传送后地址加4
| FD
| 满递减堆栈
| IB
| 每次传送前地址加4
| ED
| 空递减堆栈
| DA
| 每次传送后地址减4
| FA
| 满递增堆栈
| DB
| 每次传送前地址减4
| EA
| 空递增堆栈
| 数据块传送操作
| 堆栈操作
|
进行数据复制时,先设置好源数据指针和目标指针,然后使用块拷贝寻址指令LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB进行读取和存储 。
进行堆栈操作操作时,要先设置堆栈指针(SP),然后使用堆栈寻址指令STMFD/LDMFD 、STMED/LDMED、STMFA/LDMFA和STMEA/LDMEA实现堆栈操作。
数据块传送
存储
| 堆栈操作
压栈
| 说明
|
| 数据块传送
加载
| 堆栈操作
出栈
| 说明
| STMDA
| STMED
| 空递减
| LDMDA
| LDMFA
| 满递减
| STMIA
| STMEA
| 空递增
| LDMIA
| LDMFD
| 满递增
| STMDB
| STMFD
| 满递减
| LDMDB
| LDMEA
| 空递减
| STMIB
| STMFA
| 满递增
| LDMIB
| LDMED
| 空递增
| ;使用数据块传送指令进行堆栈操作
STMDA R0!,{R5-R6}将R5、R6存入相应的R0指向的地址对应的内存
. . .
LDMIB R0!,{R5-R6}将R0指向的地址对应的内存的内容存入R5和R6
;使用堆栈指令进行堆栈操作
STMED R13!,{R5-R6}
. . .
LDMED R13!,{R5-R6}这一段代码的两个都是ED
两段代码的执行结果是一样的,但是使用堆栈指令的压栈和出栈操作编程很简单(只要前后一致即可),而使用数据块指令进行压栈和出栈操作则需要考虑空与满、加与减对应的问题。(相当于堆栈指令做了封装) |
|