1.移动指令
MOV 将32位的值移到一个寄存器中 Rd=N
MVN 将32位的值取反后移到一个寄存器中 Rd=~N
MOV PC,R0 ;PC=R0,程序跳转到指定地址
mov r9, sp
将sp寄存器中的值复制到r9中
mov r0, #0
将寄存器r0的值设为0
mvn r1, #0
将寄存器r0的值设为0xffffffff
2.移位器
逻辑左移LSL、逻辑右移LSR、算术右移ASR、循环右移ROR和扩展的循环右移RRX。
e.g:1010101010,其中[]是添加的位
逻辑左移一位:010101010[0]
算数左移一位:010101010[0]
逻辑右移一位:[0]101010101
算数右移一位:[1]101010101
不同于其他的:在算术右移中,将一个二进制数的所有位向右移动,丢弃最右侧的位,并在最左侧插入与符号位相同的值,以保持有符号数的符号不变。也就是说,如果符号位为0,则插入0;如果符号位为1,则插入1
mov r1, r1, LSL #9
表示r1=(r1<<9)
3.算术指令
<instruction>{<cond>}{S} Rd, Rn, N
常用算术指令:
ADC 带进位的加法 Rd=Rn+N+carry
ADD 加法 Rd=Rn+N
RSB 反向减法 Rd=N–Rn
RSC 带借位的反向减法 Rd=N–Rn-!(carry flag)
SBC 带借位的减法 Rd=Rn–N-!(carry flag)
SUB 减法 Rd=Rn–N
sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
S_FRAME_SIIE值由宏#define S_FRAME_SIZE72定义,所以,
第一行指令的结果是sp=sp-72;第二行指令的结果是r0=sp+72。
ADD r0, r1, r1, LSL #2
该行指令的结果是r0=r1+(r1<<2),也就是r0=r1*5。
5.逻辑运算指令
AND 两个32位数值的逻辑与操作 Rd=Rn&N
ORR 两个32位数值的逻辑或操作 Rd=Rn|N
EOR 两个32位数值的逻辑异或操作 Rd=Rn^N
BIC 逻辑清位操作 Rd=Rn&~N
and r1, r0, #0x1f @ mask mode bits
orr r0, r0, #0xc0 @ disable FIQ and IRQ
第一行指令的结果是r1=r0&0x1f;第二行指令的结果是r0=r0|0xc0。
6.比较指令
CMN 否定比较 依照Rn+N的结果来设定标志位
CMP 比较 依照Rn–N的结果来设定标志位
TEQ 测试两个32位数是否相等 依照Rn^N的结果来设定标志位
TST 测试一个32位数的位 依照Rn&N的结果来设定标志位
teq r1, #0x1a @ test for HYP mode
该行的含义为比较r1是否等于0x1a,并设定标志位,这样后面的
指令可以根据标志位来条件执行
7.乘法指令
MLA 乘法和累加 Rd=(Rm*Rs)+Rn
MUL 乘法 Rd=Rm*Rs
SMLAL 有符号的长乘法累加 [RdHi,RdLo]=[RdHi,RdLo]+(Rm*Rs)
SMULL 有符号的长乘法 [RdHi,RdLo]=Rm*Rs
UMLAL 无符号的长乘法累加 [RdHi,RdLo]=[RdHi,RdLo]+(Rm*Rs)
UMULL 无符号的长乘法 [RdHi,RdLo]=Rm*Rs
mla r3,r4,r1,r3
该行的执行结果是r3=(r4*r1)+r3。
8.分支指令
分支指令改变程序执行流程或者用于调用子程序。该类指令可以
使得程序有子程序、if-then-else结构和循环。
B 跳转 PC=label
BL 带返回的跳转 PC=label,lr=执行BL后下一条指令的地址
BX 跳转并切换状态 PC=Rm&0xfffffffe,T=Rm&1
BLX 带返回的分支并切换状态 PC=label,T=1
PC=Rm&0xfffffffe,T=Rm&1,lr为执行BLX后下一条指令的地址
跳转指令在程序中使用得最多,函数的调用应该都是用跳转指令
实现的。
bl cpu_init_cp15
bl cpu_init_crit
9.软中断指令
软中断指令会引起软件中断异常,这为操作系统中应用程序调用
系统历程提供了一种机制
LDR R0,[LR,#-4]
该指令将链接寄存器LR的内容减去4后所获得的值作为一个地址,然后把该地址的内容装载进R0。此时再使用下面指令,immed_24操作数的内容就保存到了R0:
BIC R0,R0,#0xFF000000
该指令将R0的高8位清零,并把结果保存到R0,意思就是取R0的低24位。
寄存器R14(LR寄存器)有两种特殊功能:
·在任何一种处理器模式下,该模式对应的R14寄存器用来保存子程序的返回地址。当执行BL或BLX指令进行子程序调用时,子程序的返回地址被放置在R14中。这样,只要把R14内容拷贝到PC中,就实现了子程序的返回(具体的子程序返回操作,这里不作详细介绍)。
·当某异常发生时,相应异常模式下的R14被设置成异常返回的地址(对于某些异常,可能是一个偏移量,一个较小的常量)。异常返回类似于子程序返回,但有小小的不同(这里不作详细介绍)。
所谓的子程序的返回地址,实际就是调用指令的下一条指令的地址,也就是BL或BLX指令的下一条指令的地址。所谓的异常的返回的地址,就是异常发生前,CPU执行的最后一条指令的下一条指令的地址。
10.程序状态寄存器指令
ARM指令集提供两条指令来直接控制程序状态寄存器(psr)。MRS
指令将cpsr或spsr的内容传到寄存器中;相反的,MSR指令将寄存器的
内容传到cpsr或spsr中。综合起来,这些指令用于读写cpsr和spsr。
mrs r0, cpsr
and r1, r0, #0x1f @ mask mode bits
teq r1, #0x1a @ test for HYP mode
bicne r0, r0, #0x1f @ clear all mode bits
orrne r0, r0, #0x13 @ set SVC mode
orr r0, r0, #0xc0 @ disable FIQ and IRQ
msr cpsr,r0
11.协处理器指令
协处理器是指令集的扩展。协处理器既可以提供额外的计算能
力,也用于控制包括Cache和存储管理在内的存储系统。协处理器指令
包括数据处理、寄存器传输和内存传输指令。这里只对协处理器做简
要说明,因为这些指令与具体的协处理器相关。注意协处理器指令只
用于带有协处理器的ARM核。
CDP 协处理器数据处理——在协处理器中执行一个操作
MRC|MCR 协处理器寄存器传输——从协处理器中移出数据或者移
入数据
LDC STC 协处理器内存传输——从协处理器中load/store内存
12.加载常量的伪指令
LDR Rd, =constant
ADR Rd, label
LDR 加载常量的伪指令 Rd=32位的常量
ADR 加载地址的伪指令 Rd=32位的相对地址
LDR R0,[R1],#-4 ;
读取R1 地址上的存储器单元内容,且R1=R1-4Rm
STR R1,[R0,#0x04] ;将R1 的数据存储到R0+0x04存储单元,R0 值不变