关于“LDR和STR——字和无符号字节加载/存储指令编码”: |
关于“LDR和STR——字和无符号字节加载/存储指令”:LDR/STR指令寻址非常灵活,它由两部分组成,其中一部分为一个基址寄存器,可以为任一个通用寄存器;另一部分为一个地址偏移量。地址偏移量有以下3种格式:
(1)立即数。立即数可以是一个无符号的数值。这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。 如:LDR R1,[R0,#0x12] (2)寄存器。寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。 如:LDR R1,[R0,R2] (3)寄存器及移位常数。寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。 如:LDR R1,[R0,R2,LSL #2] 从寻址方式的地址计算方法分,加载/存储指令有以下4种格式: (1)零偏移。 如:LDR Rd,[Rn] (2)前索引偏移。 如:LDR Rd,[Rn,#0x04]! (3)程序相对偏移。 如:LDR Rd,labe1 (4)后索引偏移。 如:LDR Rd,[Rn],#0x04 注意:大多数情况下,必须保证字数据操作的地址是32位对齐的。 关于“LDR和STR——半字和有符号字节加载/存储指令”:这类LDR/STR指令可加载有符号半字或字节,可加载/存储无符号半字。偏移量格式、寻址方式与加载/存储字和无符号字节指令相同。 LDR{cond}SB Rd,<地址> ;将指定地址上的有符号字节读入Rd LDR{cond}SH Rd,<地址> ;将指定地址上的有符号半字读入Rd LDR{cond}H Rd,<地址> ;将指定地址上的半字数据读入Rd STR{cond}H Rd,<地址> ;将Rd中的半字数据存入指定地址 注意:1.有符号位半字/字节加载是指用符号位加载扩展到32位,无符号半字加载是指用零扩展到32位; 2.半字读写的指定地址必须为偶数,否则将产生不可靠的结果; |
下面介绍一下,LDR和STR指令应用示例:
1.加载/存储字和无符号字节指令LDR R2,[R5] ;将R5指向地址的字数据存入R2STR R1,[R0,#0x04] ;将R1的数据存储到R0+0x04地址LDRB R3,[R2],#1 ;将R2指向地址的字节数据存入R3,R2=R2+1STRB R6,[R7] ;将R7指向地址的字节数据存入R6 2.加载/存储半字和有符号字节指令LDRSB R1,[R0,R3] ;将R0+R3地址上的字节数据存入R1;高24位用符号扩展LDRH R6,[R2],#2 ;将R2指向地址的半字数据存入R6,高16位用0扩展;读出后,R2=R2+2STRH R1,[R0,#2]! ;将R1的半字数据保存到R0+2地址,只修改低2字节数据,R0=R0+2 |
多寄存器加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器;STM为存储多个寄存器。允许一条指令传送16个寄存器的任何子集或所有寄存器。它们主要用于现场保护、数据复制、常数传递等。
多寄存器加载/存储指令格式如下: (1)LDM{cond}<模式> Rn{!},reglist{^} (2)STM{cond}<模式> Rn{!},reglist{^} cond:指令执行的条件; 模式:控制地址的增长方式,一共有8种模式; !:表示在操作结束后,将最后的地址写回Rn中; reglist :表示寄存器列表,可以包含多个寄存器,它们使用“,”隔开,如{R1,R2,R6-R9},寄存器由小到大排列; ^:加入该后缀后,进行数据传送且寄存器列表不包含PC时,加载/存储的寄存器是用户模式下的,而不是当前模式的寄存器。若在LDM指令且寄存器列表中包含有PC时使用,那么除了正常的多寄存器传送外,还将SPSR也拷贝到CPSR中,这可用于异常处理返回。 注意:该后缀不允许在用户模式或系统模式下使用。 关于“LDM和STM——多寄存器加载/存储指令编码”: |
多寄存器加载/存储指令的8种模式如下表所示,右边四种为堆栈操作、左边四种为数据传送操作。
|
进行数据复制时,先设置好源数据指针和目标指针,然后使用块拷贝寻址指令LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB进行读取和存储 。
进行堆栈操作操作时,要先设置堆栈指针(SP),然后使用堆栈寻址指令STMFD/LDMFD 、STMED/LDMED、STMFA/LDMFA和STMEA/LDMEA实现堆栈操作。 |
堆栈操作(详见“4.1 寻址方式堆栈寻址”)和数据块传送指令类似,也有4种模式,它们之间的关系如下表所示:
|
两段代码的执行结果是一样的,但是使用堆栈指令的压栈和出栈操作编程很简单(只要前后一致即可),而使用数据块指令进行压栈和出栈操作则需要考虑空与满、加与减对应的问题。
关于“ARM存储器访问指令——寄存器和存储器交换指令”: |
SWP指令用于将一个内存单元(该单元地址放在寄存器Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单元中。使用SWP可实现信号量操作。
指令格式如下: SWP{cond}{B} Rd,Rm,[Rn] 其中,B为可选后缀,若有B,则交换字节,否则交换32位字;Rd用于保存从存储器中读入的数据;Rm的数据用于存储到存储器中,若Rm与Rn相同,则为寄存器与存储器内容进行交换;Rn为要进行数据交换的存储器地址,Rn不能与Rd和Rm相同。 SWP和SWPB——寄存器和存储器交换指令编码 |
关于“ARM指令集——ARM数据处理指令”:数据处理指令大致可分为3类:
(1)数据传送指令;(2)算术逻辑运算指令;(3)比较指令。 数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。所有ARM数据处理指令均可选择使用S后缀,并影响状态标志。 下面讲讲“ARM数据处理指令——指令编码”: |
电工学习网 ( )
GMT+8, 2021-12-6 20:44