ARM汇编不必去记忆每一条汇编指令,学习指令集最好是结合具体实验,先将基本的指令用熟,遇到新指令时查一下相关指令集手册即可。
ARM处理器是基于精简指令集计算机(RISC)原理设计的,指译码令集的机制较为简单,ARM920T具有32位ARM指令集和16位Thumb指令集。ARM指令集执行效率高,但是代码密度相对较低,而Thumb指令集是ARM指令集的子集,具有更好的代码密度,而且保持了ARM的大多数性能上的优势。
所有ARM指令都是可以有条件执行的,而Thumb指令仅有一条指令具备条件执行功能。ARM程序和Thumb程序可以相互调用,相互之间切换开销可以忽略不计。但是初学者的确很少涉及或者用不到Thumb指令,可以大胆放弃,等学完了ARM指令集后如果本身项目需要Thumb指令的地方,可以自行学习。学完ARM指令集,Thumb指令集就很简单了。
ARM指令集:<启动代码中的ARM指令>
基本格式:{}{S},{,}
其中,<助记符>内的项是必须的,{<指令执行条件>}内的项是可选的,如果不写则使用默认条件是无条件执行。{S}决定是否影响CPSR寄存器的值,书写影响,否则不影响。Rd是目标寄存器,Rn是第一个操作数的寄存器。
1. 存储器访问指令:ARM处理器对ROM、RAM和I/O地址采取统一编址,除对RAM操作以外,对外围IO、程序数据访问均要通过加载/存储(Load/Store)指令进行。ARM的加载/存储指令可以实现字、半字、无符/有符字节操作;批量加载/存储(Load/Store)指令可实现一条指令加载/存储多个寄存器的内容,大大提高效率。
LDR:从内存中读取数据加载到寄存器;LDR R0,[R1],将R1所指向的存储单元的内容加载到R0寄存器中。
STR:用于将寄存器中数据保存到内存;STR R0,[R1],将R0里面的内容存储到R1所指向的存储单位中。
LDM/STM 批量加载/存储指令,实现在对多个寄存器和一块连续的内存单元之间传输数据(参数传递和数据复制)。
LDM指令实现加载一块连续内存单元的数据到多个寄存器;
STM将多个存储器的内容存储到一块连续的内存单元中;
LDM {cond} Rn{!},{reglist}{^}
STM {cond} Rn{!},{reglist}{^}
cond ,执行条件;
mode ,总共有8种,对应初学者,只需要掌握IA(递加4),FD模式(递减4)即可。
Rn,为基址寄存器,注意Rn不允许为R15(程序计数器PC)。
后缀“!”表示将最后的地址会写到Rn中。
Reglist,是寄存器列表,可以包含多个寄存器,寄存器按由小到大的顺便排列,当寄存器标号连续时,用“-”连接,如标号不连续时,英逗号。
后缀“^”
LDMIA R0,{R1-R4} 即将R0指向的存储单元(实际上是4个字节(32位),因为ARM指令是字对齐的)的内容加载到寄存器R1~R4中。IA,increase After,先传数据,然后更新地址值(increase the address after transforming the data to the register),R0的值一直没有变化。
LDMIA R0!,{R1-R4},即将R0指向的存储单元(实际上4个字节,因为ARM指令时字对齐的)的内容加载到寄存器R1~R4中。地址值每加4,都会赋值给R0,R0值会更新。
2.数据处理指令
MOV
MOV R0,#8 ;R0=8;
MOV R0,R1 ;R0=R1;
MOV R0,R1,LSL #3;将R1的内容左移三位,然后传送到R0,即R0=(R1<<3).
MOV PC,LR;该指令可以实现子程序的返回,其中,PC和LR是ARM汇编器对ARM的寄存器进行了预先定义,PC即R15,LR即R14,因此该指令相当于MOV R15,R14。
ADD(加法指令)、SUB(减法指令)、BIC(位清除指令)、ORR(逻辑或)
ADD R0,R1,#1;R0=R1 1;
ADDS R0,R1,#1;R0=R1 1;指令后有个S,意思是该条指令执行后可能会影响当前程序状态寄存器CPSR中的条件标志位。
BIC R0,R0,#0xF,将R0的后4位清零,将结果保存到R0中。
ORR R0,RO,#0xF,将R0的后4位置1,将结果保存在R0中。
CMP、TST
CMP是比较指令,CMP {cond}Rn,operand2 执行过程:将寄存器Rn的值减去operand2的值,根据操作的结果更新CPSR中相应的条件标志位,以便后面的指令根据相应的条件标志位来判断是否执行。
TST是位测试指令,TST {cond}Rn,operand2 执行过程:将寄存器Rn的值与operand2的值按位进行逻辑与操作,根据操作结果更新CPSR中相应的条件标志位,以便后面指令根据相应的条件标志位来判断是否执行。
跳转指令:B和BL
B {cond}label 基本功能:即直接跳转到指定的地址去执行。需要注意的是,使用B指令实现程序跳转时,程序的跳转范围为正负32Mb。
BL是带返回地址的跳转,指令自动将下一条指令的地址复制到链接寄存器R14(LR)中,然后跳转到指定的地址去执行,执行完后,返回到跳转前指令的下一条指令出执行。
程序状态寄存器访问指令:在ARM中,对程序状态寄存器(当前程序状态寄存器CPSR和备份程序状态寄存器SPSR)的操作是通过专门的指令(MSR和MRS)来实现的,其他指令不能实现对程序状态器的操作。通过读-修改-写操作来实现开关中断,切换处理器模式等。
MRS读程序状态寄存器指令,MRS {cond} Rd,psr,将程序状态寄存器psr中的内容读入到目标寄存器Rd中。
MSR写程序状态寄存器指令,MSR {cond} psr_fields,#immed_8r或者MSR {cond} psr_fields,Rm.
ARM处理器的工作模式分为用户模式和特权模式,除用户模式外的其他六种模式为特权模式,只有在特权模式下才能对程序状态寄存器进行修改。
例如:将处理器工作模式切换到管理模式:
MSR CPSR_c,#0xD3,将0xD3写入到CPSR的低8位,因为此时M[4:0]=0b10011,所以系统进入管理模式。
例如:运用"读-修改-写"的方法将处理器的工作模式切换到管理模式
MRS R0,CPSR ;将CPSR的内容读入到R0
BIC R0,R0,#0x1F;将CPSR中与模块控制有关的位清零。
ORR R0,R0,#0xD3; 重新修改CPSR中模式控制位(其中ORR是或运算指令)
MSR CPSR_cxsf,R0; 将修改后的值写到CPSR中。
ARM中的程序状态寄存器(CPSR)
31 | 30 | 29 | 28 | 27 | ~ | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |||
N | Z | C | V | 保留 | I | F | T | M4 | M3 | M2 | M1 | M0 | |||||
N | Negative/Less Than | I | IRQ disable | ||||||||||||||
Z | Zero | F | FIQ disable | ||||||||||||||
C | Carry/Borrow/Extend | T | State bit | ||||||||||||||
V | Overflow | M0~4 | Mode bits |
协处理器访问指令:
在ARM系统中,协处理器CP15主要用于存储管理,CP15总共包含了16个32位的寄存器,其编号为C0~C15.在裸机开发中,很少涉及对协处理器的访问(当修改处理器总线模式的时候会用到)。
访问协处理器的指令为MCR和MRC。
MRC:协处理器到ARM寄存器的数据传送指令。该指令可以讲协处理器的寄存器中的数据传送到ARM处理器寄存器中。
MRC {cond} p15, 0, Rd, CRn,CRm {, opcode2}
Rd是ARM中的寄存器,作为目标寄存器。
CRn是协处理器中的寄存器,作为源寄存器,存放第一个操作数器编号为C0,C1,……,C15.
CRm是附加的源寄存器,当指令中不需要提供其他信息时,CRm应指定为C0.
opcode2用于提供附加信息,当指令中没有附加信息时,将其制定为0即可。
MCR:ARM寄存器到协处理器寄存器的数据传送指令。该指令可以将ARM处理器寄存器中的数据传送到协处理器的寄存器中。
MCR {cond} p15, 0, Rd, CRn,CRm {, opcode2}
mrc p15,0,r0,c1,c0,0该指令的功能是将协处理器c1中的内容读入到ARM处理器R0中。
mcr p15,0,r0,c1,c0,0该指令的功能是将ARM处理器r0的内容写入到协处理器寄存器c1中。