ARM指令集一(学习日记) - [ARM7TDMI]
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://kellycan.blogbus.com/logs/10699076.html
1.存储器访问指令
ARM处理器是RISC构架的处理器,不能像CISC构架的处理器那样让存储器中的内容直接参与运算,而需要将存储器单元的内容先读到内部寄存器中。对存储器的访问只能通过加载和存储指令实现。
(1)LDR/STR--加载/存储指令
LDR指令用于从内存中读取数据放入寄存器中,STR用于将寄存器中的数据保存到内存中,LDR/STM搭配不同的后缀可实现字节(后缀为B),半字(后缀为H),或字数据的访问。当指令有有后缀T时,那么即使处理器在特权模式下,存储系统也将访问看成是在用户模式下。T在用户模式下无效,且不能与前索引偏移一起使用T。
按寻址方式的地址计算方式分,加载和存储可分为四种形式:
* 零偏移:Rn的值作为传送数据的地址,即偏移量为0,如:
LDR Rd,[Rn]
*前索引偏移:在数据传输之前,将偏移量加到Rn中,其结果作为传送数据的存储地址,若使用后缀“!”,则结果回写到Rn中,且Rn的值不允许为R15,如
LDR Rd,[Rn,#0x04]! Rd=[Rn+4],Rn=Rn+4
LDR Rd,[Rn,#0x04] Rd=[Rn+4],Rn=Rn
*程序相对偏移:是前索引形式的另一个版本,。汇编器由PC寄存器计算偏移量,并将PC寄存器作为Rn生成前索引指令。不能使用后缀“!”。如:
LDR PC,Label
注意:Label是程序标号,必须在当前指令的前后的4kb范围内,中断向量表中程序的散转就使用这条指令。
*后索引偏移:Rn的值作为数据传输的存储地址,在数据传输以后,将偏移量与Rn相加,结果写回到Rn中,RN不允许是R15。如:
LDR Rd,[Rn],#0x04 Rd=[Rn],Rn=Rn+4
(2)LDM/STM--多存储器加载/存储指令
实现在一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器;STM为存储多个寄存器。允许一条指令传送16个寄存器的任何子集或所有寄存器。它们主要用于现场保护、数据复制、常数传递等。
多寄存器加载/存储指令的8种模式其中四种为堆栈操作、四种为数据传送操作。
进行数据复制时,先设置好源数据指针和目标指针,然后使用块拷贝寻址指令LDMIA/STMIA、LDMIB/STMIB、LDMDA/STMDA、LDMDB/STMDB进行读取和存储 。
进行堆栈操作操作时,要先设置堆栈指针(SP),然后使用堆栈寻址指令STMFD/LDMFD 、STMED/LDMED、STMFA/LDMFA和STMEA/LDMEA实现堆栈操作。
如:LDMFD Rn{!},reglist{^}
注意:*Rn不允许为R15;
*Rn指向执行指令前的起始地址,当Rn后带“!”,则最后的地址回写到Rn中,无“!”,则Rn的内容保持不变;
*寄存器与内存单元的对应关系为,编号低的寄存器对应于低地址单元,编号高的寄存器对应于高地址单元;
*“^”不允许在用户和系统模式下使用,当在LDM指令中且reglist中有PC时,除了正常的多寄存器传送外,还会把SPSR的值拷贝到CPSR,用于异常的返回,而无“^”时,适用于子程序的返回;
*当使用“^”且reglist中没有PC时,则加载/存储的是用户模式的寄存器而不是当前模式的寄存器。
(3)SWP和SWPB--寄存器和存储器交换指令编码
SWP指令用于将一个内存单元(该单元地址放在寄存器Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单元中。使用SWP可实现信号量操作。
指令格式如下:SWP{cond}{B} Rd,Rm,[Rn]
其中,B为可选后缀,若有B,则交换字节,否则交换32位字;Rd用于保存从存储器中读入的数据;Rm的数据用于存储到存储器中,若Rm与Rn相同,则为寄存器与存储器内容进行交换;Rn为要进行数据交换的存储器地址,Rn不能与Rd和Rm相同。
2.数据处理指令
数据处理指令大致可分为3类: 数据传送指令(MOV等),算术逻辑运算指令(ADD等),比较指令(CMP等)。
数据处理指令只能对寄存器的内容进行操作,而不能对内存中的数据进行操作。所有ARM数据处理指令均可选择使用S后缀,并影响状态标志。而比较指令CMP,CMN,TST和TEQ不需要后缀S,他们会直接影响状态标志。
3.ARM分支指令
在ARM中有两种方式可以实现程序的跳转:使用分支指令直接跳转和直接向PC寄存器赋值实现跳转。
分支指令有分支指令B,带链接的分支指令BL,带状态切换的分支指令BX。
(1)分支指令--B
格式:B{cond} Label
B指令用于跳转到指定的地址执行程序。
跳转的范围限制为当前指令的±32M字节范围内。
(2)带链接的分支指令--BL
格式:BL{cond} Label
BL指令先将下一条指令的地址拷贝到R14(即LR)链接寄存器中,然后跳转到指定地址运行程序。
分支指令BL跳转的范围限制为当前指令的±32M字节范围内,BL指令用于子程序的调用。
(3)带状态切换的分支指令--BX
格式:BX{cond} Rm
BX指令跳转到Rm指定的地址执行程序,根据跳转地址(Rm)的最低位来切换处理器状态,当Rm的位[0]为1,目标地址的代码解释为Thumb代码,当Rm的位[0]为0,目标地址的代码解释为ARM代码。其跳转范围限制在当前指令的±32M字节地址内(ARM指令为字对齐,最低2位地址固定为0) 。