在早期的 ARM 处理器中,使用了 32 位指令集,称为 ARM 指令。这个指集具有较高的运行性能。与8 位和 16 位的处理器相比,有更大的程序存储空间。但是,也带来较大的功耗。
在1995 年,16 位的 Thumb-1 指令集首先应用在ARM7TDMI 处理器上使用,它是 ARM指令集的子集。与 32 位的 RISC 结构相比,它提供更好的代码密度,将代码长度减少了 30%,但是性能也降低了20%。通过使用多路复用器,它能与 ARM 指令集一起使用。
Thumb-2 指令集由32位的Thumb 指令和最初的16位Thumb 指令组成与32位的ARM指令集相比,代码长度减少了 26%,但保持相似的运行性能。
Cortex-Mo采用了ARMv6-M 的结构,将电路规模降低到最小,它采用了16位Thumb-1的超集,以及 32位Thumb-2 的最小子集。下表给出了 Cortex-M0支持的 Thumb 指令以及Cortex-M0支持的32位Thumb 指令。
ARM 汇编语言(适用于 ARM RealView 开发组件和 Keil)使用下面的指令格式:
标号
助记符 操作数 1 操作数 2,… ;注释
其中:
对于不同类型的指令,操作数数量也会有所不同。有些指令不需要任何操作数,而有些指令只需要一个操作数。
例如:
对于下面的指令:
MOVS R3,#0x11 ;将立即数 0x11 复制到 R3 寄存器
可以通过ARM汇编器 (armasm) 或者不同厂商的汇编工具 (GNU工具链)对该代码进行汇编,将其转换成机器指令。当使用 GNU 工具链时,对标号和注释的语法会稍有不同。
对于 Cortex-M0的一些指令来说,需要在其后面添加后缀
后缀 | 标志 | 含义 |
---|---|---|
S | _ | 更新APSR(标志) |
EQ | Z=1 | 等于 |
NE | Z=0 | 不等于 |
CS/HS | C=1 | 高或者相同,无符号 |
CC/LO | C=0 | 低,无符号 |
MI | N=1 | 负数 |
PL | N=0 | 正数或零 |
VS | V=1 | 溢出 |
VC | V=0 | 无溢出 |
HI | C=1和Z=0 | 高,无符号 |
LS | C=0或Z=1 | 低或者相同,无符号 |
GE | N=V | 大于或者等于,有符号 |
LT | N!=V | 小于,有符号 |
GT | Z=0和N=V | 大于,有符号 |
LE | Z=1和N!=V | 小于等于,有符号 |
该指令将立即数 immed8(8位,范围 0-255)复制到存器Rd中
例如:
MOV R0,#0x31
将寄存器R1的内容复制到寄存器R0中
该指令将Rm寄存器的内容复制到Rd寄存器中
例如:
MOV R0,R1
将寄存器R1的内容复制到寄存器R0中。
该指令将立即数immed8(8位,范围0~255)复制到寄存器 Rd 中,并且更新APSR寄存器中的Z和N 标志
例如:
MOVS R0,#0x31
将数字 0x31(十六进制)复制到寄存器R中(低8位),并且更新 APSR 寄存器中的Z和N标志。
该指令将Rm寄存器的内容复制到Rd寄存器中,并且更新APSR寄存器中的Z和N标志
例如:
MOVS R0,R1
将寄存器R1的内容复制到寄存器R0中,并且更新APSR寄存器中的标志。
该指令将由SpecialReg标识的特殊寄存器内容复制到寄存器Rd中,该指令不影响APSR寄存器中的任何标志位
例如:
MRS R1,CONTROL
将CONTROL寄存器的内容复制到寄存器R1中。
该指令将寄存器Rd中的内容复制到SpecialReg标识的特殊寄存器中,该指令影响 APSR寄存器中的N、Z、C和V标志
例如:
MSR PRIMASK,R0
将寄存器R0的内容复制到PRIMASK寄存器中。
SpecialReg所标识的特殊寄存器可以是以下任意一个:
APSR、IPSR、EPSR、IEPSR、IAPSR、EAPSR、PSR、MSP、PSP、PRIMASK、CONTROL。
这些指令不影响APSR寄存器中的任何标志位。
该指令从[Rn+Rm]寄存器所指向存储器的地址中,取出一个字(32 位),并将其复制到寄存器Rt中
例如:
LDR R0,[R1,R2]
该指令从[R1+R2]所指向存储器的地址中,取出一个字(32 位),并将其复制到寄存器R0中。
该指令从[Rn+Rm]寄存器所指向存储器的地址中,取出半个字(16 位),将其复制到寄存器Rt的[15:0]位中,并将寄存器Rt的[31:16]位清零
例如:
LDRH R0,[R1.R2]
该指令从[RI+R2]所指向存储器的地址中,取出半个字(16位),将其复制到存器R0的[15:0]位中。
该指令从[Rn+Rm]寄存器所指向存储器的地址中,取出一个字节(8 位),将其复制到寄存器Rt的[7:0]位中,并将寄存器Rt的[31:8]位清零,
例如:
LDRB R0,[R1,R2]
该指令从[R1+R2]寄存器所指向存储器中,取出一个字节(8 位),并将其复制到存器R0的[7:0]位中。
该指令从[Rn + 零扩展(=immed5<<2)]指向存储器的地址中,取出一个字(32 位),并将其复制到寄存器Rt的[31:0]位中。
例如:
LDR R0,[R1,#0x4]
该指令从[R1+0x4]所指向存储器的地址中,取出一个字 (32 位),并将其复制到寄存器R0中。
零扩展(#immed5<<2),表示给出立即数#immed5 的范图为0000000~1111111(即从0-127),并且满足字对齐关系,即:#immed5%4=0。
如下指令非法:
LDR R0,[R1,#80] ;立即数超过范围,80为128,超过127的范围
LDR R0,[R1,#7E] ;立即数7E没有字对齐#immed5为16进制数
该指令从[Rn+零扩展(immed5<<1)]指向存储器的地址中,取出半个字(16 位),并将其复制到寄存器 Rt的[15:0]位中,用零填充[31:16]位。
例如:
LDRH R0,[R1,#0x2]
该指令从[R1+0x2]指向存储器的地址中,取出半个字(16 位),并将其复制到寄存器R0的[15:0]中,[31:16]用零填充。
零扩展 (#immed5<<1),表示给出立即数#immed5 的范图为 000000~111111(即从0-63),并且满足字对齐关系,即:#immed5%2=0。
如下指令非法:
LDR R0,[R1,#40] ;立即数超过范围,40为64,超过63的范围
LDR R0,[R1,#3E] ;立即数3E没有字对齐
该指令将立即数加载到寄存器 Rt 中。
例如:
LDR R0,=0x12345678
该指令将立即数0x12345678的值复制到寄存器R0中。
该指令从[PC(SP) +零扩展 (#immed8<<2)]指向存储器的地址中,取出一个字(32位),并将其复制到寄存器 Rt中。
例如:
LDR R0,[PC,#0x04]
该指令从[(PC)+0x04]指向存储器的地址中,取出一个字,并将其复制到寄存器R0中。
零扩展(#immed8<<2),表示给出立即数#immed8 的范围为0000000000~1111111111(即从0-1023),并且满足字对齐关系,即:#immed8%4=0。
该指令从[Rn+Rm]所指向的存储器中取出半个字(16 位),并将其复制到Rt寄存器的[15:0]位中。对于[31:16]来说,取决于第[15]位,采用符号扩展。
例如:
LDRSH R0,[R1,R2]
该指令从[R1+R2]所指向的存储器地址中取出半个字 (16 位),并将其复制到R0寄存器的[15:0]位中,并进行符号扩展。
从[Rn+Rm]所指向存储器的地址中取出一个字节 (8 位),并将其复制到 R 寄存器[7:0]中。对于[31:8]来说,取决于第[7]位,采用符号扩展。
例如:
LDRSB R0,[R1,R2]
该指令从[R1+R2]所指向的存储器中取出一个字节 (8 位),并将其复制到R0寄存器的[7:0]位中,并进行符号扩展。
这些指令不影响APSR寄存器中的任何标志位。
该指令将Rt寄存器中的字数据复制到[Rn+Rm]所指向存储器的地址单元中
例如:
STR R0,[R1,R2]
该指令将 R0 寄存器中的字数据复制到[R1+R2]所指向存储器地址单元中
该指令将Rt寄存器的半字,即:[15:0]位复制到[Rn+Rm]所指向存储器的地址单元中
例如:
STRH R0,[R1,R2]
该指令将R0寄存器中的[15:0]位数据复制到[R1+R2]所指向存储器的地址单元中。
该指令将Rt寄存器的字节,即:[7:0]位复制到[Rn+Rm]所指向存储器的地址单元中
例如:
STRB R0,[R1,R2]
该指令将R0寄存器中的[7:0]位复制到[R1+R2]所指向存储器的地址单元中。
该指令将Rt寄存器的字数据复制到[Rn+零扩展 (#immed5<<2)]所指向存储器地址的单元中。
例如:
STR R0,[R1,#0x4]
将R0寄存器的字复制到[R1+0x04<<2]所指向存储器地址的单元中。
该指令将Rt寄存器的半字数据复制到[Rn+零扩展 (#immed5<<1)]所指向存储器地址的单元中。
例如:
STRH R0,[R1,#0x2]
将R0寄存器的半字复制到[R1+0x02]所指向存储器地址的单元中。
该指令将Rt寄存器的字节数据复制到[Rn+零扩展 (#immed5)]所指向存储器地址的单元中。
例如:
STRB R0,[R1,#0x1]
将R0寄存器的字节复制到[R1+0x01]所指向存储器地址的单元中。
该指令将Rt寄存器中的字数据复制到[SP+零扩展(#immed5<<2)]所指向存储器地址的单元中
STRB R0,[SP,#0x4]
该指令将将R0寄存器的字数据复制到[SP+(0x4)所指向存储器地址的单元中。
该指令将存储器的内容加载到多个寄存器中。
例如:
LDM R0,{R1,R2-R7}
将寄存器R0所指向存储器地址单元的内容复制到寄存器R1中。
将寄存器R0+4所指向存储器地址单元的内容复制到寄存器R2中。
将奇存器R0+8所指向存储器地址单元的内容复制到寄存器R3中。
…
将寄存器R0+24所指向存储器地址单元的内容复制到寄存器R7中。
该指令将存储器的内容加载到多个寄存器中,然后将Rn的值更新到最后一个地址+4的值。
例如:
LDMLA R0,{R1,R2-R7}
将寄存器R0所指向存储器地址单元的内容复制到寄存器R1中。
将寄存器R0+4所指向存储器地址单元的内容复制到寄存器R2中。
将寄存器R0+8所指向存储器地址单元的内容复制到寄存器R3中。
…
将寄存器R0+24所指向存储器地址单元的内容复制到寄存器R7中。
最后,将R0的值更新到最初R0+24+4的值。
! 表示更新寄存器 Rn 的值。
该指令将多个寄存器的内容保存到存储器中,然后将Rn的值递增到最后一个地址+4的值。
例如:
STMIA R0!,{R1,R2-R7}
将寄存器R1的内容复制到寄存器R0所指向存储器地址的单元中。
将寄存器R2的内容复制到寄存器R0+4所指向存储器地址的单元中。
将寄存器R3的内容复制到寄存器R0+8所指向存储器地址的单元中。
…
将寄存器R7的内容复制到寄存器R0+24所指向存储器地址的单元中。
最后,将R0的值更新到最初R0+24+4的值。
! 表示更新寄存器 Rn 的值。
可用的寄存器范围为R0~R7。
对于STM来说,如果Rn也出现在列表中,则Rn应该是列表中的第一个寄存器。
该指令将一个/多个寄存器保存到寄存器(入栈),并且更新堆栈指针寄存器
例如:
PUSH {R0,R1,R2}
最后,将SP-12的结果作为SP最终的值
该指令将存储器中的内容恢复到多个寄存器中,并且更新堆栈指针寄存器
例如:
POP {R0,R1,R2}
最后,将SP+12的结果作为SP最终的值。
算术运算指令包括加法指令、减法指令和乘法指令
该指令将Rn寄存器的内容和Rm寄存器的内容相加,结果保存在寄存器Rd中,并且更新寄存器APSR中的N、Z、C和V标志
例如:
ADDS R0,R1,R2
该指令将R1寄存器的内容和R2寄存器的内容相加,结果保存在寄存器R0中,并且更新寄存器APSR中的标志。
该指令将Rn寄存器的内容和立即数#immed3(该立即数的范围为000~111之间)相加,结果保存在寄存器Rd中,并且更新寄存器APSR中的 N、Z、C 和V标志
例如:
ADDS R0,R1,#0x01
该指令将R1寄存器的内容和立即数0x01相加,结果保存在寄存器R0中,并且更新寄存器APSR中的标志。
该指令将Rd寄存器的内容和立即数#immed8(该立即数的范围为 00000000~11111111之间)相加,结果保存在寄存器Rd中,并更新寄存器APSR中的N、Z、C和V标志
例如:
ADDS R0,#0x01
该指令将R0寄存器的内容和立即数0x01相加,结果保存在寄存器R0中,并且更新寄存器APSR中的标志。
该指令将Rd寄存器的内容和Rm寄存器的内容相加,结果保存在寄存器Rd中,不更新寄存器APSR中的标志
例如:
ADD R0,R1
该指令将R0寄存器的内容和R1寄存器的内容相加,结果保存在寄存器R0中,不更新寄存器APSR中的标志。
该指令将Rd寄存器的内容、Rm寄存器的内容和进位标志相加,结果保存在寄存器Rd中,并且更新寄存器APSR 中的N、Z、C和V标志。
例如:
ADCS R0,R1
该寄存器将R0寄存器的内容、R1寄存器的内容和进位标志相加,结果保存在寄存器R0中并且更新寄存器APSR中的标志。
该指令将PC寄存器的内容和立即数immed8相加,结果保存在寄存器Rd中,不更新奇存器APSR中的标志。
例如:
ADD R0,PC,#0x04
该指令将PC寄存器的内容和立即数0x04相加,结果保存在寄存器R0中,不更新存器APSR中的标志。
该立即数#immed8的范国为0x00000000~0x000003FF(0-1023)之间,且#immed8%4=0。
该指令将PC寄存器的内容与标号所表示的偏移量进行相加,结果保存在寄存器Rd中,不更新APSR中的标志。
例如:
ADR R3,JumpTable
该指令将 JumpTable 的地址加载到寄存器R3中。
标号必须是字对齐,且范围在0~1020个字节内,可以在汇编语言中使用ALIGN命令实现标号的字对齐。
该指令将寄存器Rn的内容减去寄存器Rm的内容,结果保存在Rd中,并且更新寄存器APSR寄存器中的N、Z、C和V 标志
例如:
SUBS R0,R1,R2
该指令将寄存器R1的内容减去寄存器R2的内容结果保存在R0中,并且更新寄存器APSR寄存器中的标志。
该指令将 Rn 寄存器的内容和立即数#immed3(该立即数的范围为 000~111之间)相减结果保存在寄存器 Rd 中,并且更新寄存器 APSR 中的 N、Z、C 和V标志
例如:
SUBS R0,R1,#0x01
该指令将 R1 寄存器的内容和立即数 0x01 相减,结果保存在寄存器 R0 中,并且更新寄存器APSR中的标志。
该指令将 Rd 寄存器的内容和立即数#immed8(该立即数的范围为 00000000~11111111之间)相减,结果保存在寄存器 Rd 中,并更新存器APSR 中的N、Z、C和V标志
例如:
SUBS R0,#0x01
该指令将 R0 寄存器的内容和立即数0x01相减,结果保存在寄存器R0中,并且更新寄存器APSR中的标志。
该指令将 Rd 寄存器的内容、Rm 寄存器的内容和借位标志相减,结果保存在寄存器 Rd中,并且更新寄存器 APSR 中的N、Z、C和V标志。
例如:
SBCS R0,R0,R1
该寄存器将R0寄存器的内容R1寄存器的内容和借位标志相减,结果保存在寄存器R0中,并且更新寄存器 APSR 中的标志。
该指令用数字0减去寄存器 Rm 中的内容,结果保存在寄存器 Rd 中,并且更新寄存器APSR 中的N、Z、C和V标志
例如:
RSBS R0,R0,#0
该指令用数字0减去寄存器R0中的内容,结果保存在寄存器R0中,并且更新寄存器 APSR中的标志。
该寄存器将寄存器 Rm 的内容和寄存器 Rd 的内容相乘,结果保存在 Rd 寄存器中,并且更新寄存器 APSR 中的 N、Z、C和V标志
例如:
MULS R0,R1,R0
该寄存器将寄存器R1的内容和寄存器R0的内容相乘,结果保存在R0寄存器中,并且更新寄存器APSR中的标志。
该指令比较寄存器 Rn 和寄存器 Rm 的内容,得到(Rn) - (Rm)的结果,但不保存该结果,并且更新寄存器 APSR 中的 N、Z、C和V标志
例如:
CMP R0,R1
该指令比较寄存器 R0 和寄存器 R1 的内容,得到(R0) - (R1)的结果,但不保存该结果,并且更新寄存器APSR中的标志。
该指令将寄存器 Rn 的内容和立即数#immed8(其范围在0x00000000~0x000000FF之间)进行比较,得到(Rn)-#immed8 的结果,但不保存该结果,并且更新寄存器 APSR 中的 N、Z、C和V标志
例如:
CMP R0,#0x01
该指令将寄存器 R0 的内容和立即数#0x01进行比较,得到(R0) - 0x01 的结果,但不保存该结果,并且更新寄存器 APSR 中的标志。
该指令比较寄存器 Rn 的内容和对寄存器 Rm 取反后内容,得到(Rn)+(Rm)的结果但不保存该结果,并且更新寄存器 APSR 中的 N、Z、C和V标志
例如:
CMN R0,R1
该指令比较寄存器 R0 和对寄存器 R1 取反后的内容,得到(R0)+(R1)的结果,但不保存该结果,并且更新寄存器 APSR 中的标志。
该指令将寄存器 Rd 和寄存器 Rm 中的内容做“逻辑与”运算,结果保存在寄存器Rd中,并且更新寄存器APSR中的N和Z标志。
例如:
ANDS R0,R1
该指令将寄存器R0和寄存器R1中的内容做“逻辑与”运算,结果保存在寄存器R0中,并且更新寄存器APSR 中的标志。
该指令将寄存器 Rd 和存器 Rm 中的内容做“逻辑或”运算,结果保存在寄存器 Rd中,并且更新寄存器 APSR 中的 N 和Z标志
例如:
ORRS R0,R1
该指令将寄存器R0和寄存器R1中的内容做“逻辑或”运算,结果保存在寄存器R0中,并且更新寄存器APSR中的标志。
该指令将寄存器 Rd 和寄存器 Rm 中的内容做“逻辑异或”运算,结果保存在寄存器 Rd中,并且更新寄存器 APSR 中的 N 和Z标志。
例如:
EORS R0,R1
该指令将寄存器 R0 和寄存器 R1 中的内容做“逻辑异或”运算,结果保存在寄存器 R0 中并且更新寄存器 APSR 中的标志。
该指令将奇存器 Rm 的[31:0]位按位做“逻辑取反”运算,结果保存在寄存器 Rd 中,并且更新寄存器 APSR 中的 N 和Z标志。
例如:
MVNS R0,R1
该指令将寄存器 R1的[31:]位按位做“逻辑取反”运算,结果保存在寄存器 R0 中,并且更新寄存器 APSR 中的标志。
该指令将寄存器 Rm 的[31:0]位按位做“逻辑取反”运算,然后与寄存器 Rd 中的[31:0]位做“逻辑与”运算,结果保存在寄存器 Rd 中,并且更新寄存器 APSR 中的 N 和Z标志
例如:
BICS R0,R1
该指令将寄存器 R1的[31:0]位按位做“逻辑取反”运算,然后与寄存器 R0 中的[31:0]位做“逻辑与”操作,结果保存在奇存器 R0 中,并且更新寄存器 APSR 中的标志。
该指令将寄存器 Rd 和寄存器 Rm 中的内容做“逻辑与”运算,但是不保存结果,并且更新寄存器 APSR 中的 N和Z标志。
例如:
TST R0,R1
该指令将寄存器 R0 和寄存器 R1 中的内容做“逻辑与”运算,但是不保存结果,并且更新寄存器APSR中的标志。
该指令执行算术右移操作。将保存在寄存器 Rd 中的数据向右移动 Rm 所指定的次数移位的结果保存在寄存器 Rd 中,即: Rd=Rd>>Rm。在右移过程中,最后移出去的位保存在寄存器 APSR 的C标志中,也更新 N 和标志。
例如:
ASRS R0,R1
该指令将保存在寄存器 R0 中的数据向右移动 R1 所指定的次数,移位的结果保存在寄存器R0中。在右移过程中,最后移出去的位保存在寄存器 APSR 的C标志中,也更新N 和Z标志。
该指令执行算术右移操作。将保存在寄存器 Rm 中的数据向右移动立即数#immed5 所指定的次数(范围在 1~32之间),移位的结果保存在寄存器 Rd 中,即: Rd=Rm>>#immed5。在右移过程中,最后移出去的位保存在寄存器 APSR的C 标志中,也更新 N 和Z标志。
例如:
ASRS R0,R1,#0x01
该指令将保存在寄存器 R1 中的数据向右移动 1 次,移位的结果保存在寄存器 R0 中在右移过程中,最后移出去的位保存在寄存器 APSR 的C标志中,也更新N 和Z标志。
该指令执行逻辑右移操作。将保存在寄存器 Rd 中的数据向右移动 Rm 所指定的次数移位的结果保存在寄存器 Rd 中,即: Rd=Rd>>Rm。在右移过程中,最后移出去的位保存在寄存器 APSR 的 C标志中,也更新 N 和Z标志。
例如:
LSRS R0, R1
该指令将保存在寄存器 R0 中的数据向右移动 R1 所指定的次数,移位的结果保存在寄存器R0中。在右移过程中,最后移出去的位保存在寄存器 APSR的C 标志中,也更新N 和Z标志。
该指令执行逻辑右移操作。将保存在寄存器 Rm 中的数据向右移动立即数#immed5 所指定的次数(范围在 1~32之间),移位的结果保存在寄存器 Rd 中,即: Rd=Rm>>#immed5。在右移过程中,最后移出去的位保存在寄存器APSR的C标志中,也更新N和Z标志。
例如:
LSRS R0,R1,#0x01
该指令将保存在寄存器 R1 中的数据向右移动 1 次,移位的结果保存在寄存器 R0 中。在右移过程中,最后移出去的位保存在寄存器 APSR的C标志中,也更新N和Z标志。
该指令执行循环右移操作。将保存在寄存器 Rd 中的数据向右循环移动 Rm 所指定的次数,移位的结果保存在寄存器 Rd中。在循环右移过程中,最后移出去的位保存在寄存器 APSR的C标志中,也更新N和Z标志
例如:
RORS R0,R1
该指令将保存在寄存器 R0 中的数据向右循环移动 R1 所指定的次数,移位的结果保存在寄存器 R0 中。在循环右移过程中,最后移出去的位保存在寄存器APSR的C标志中,也更新N和Z标志。
该指令执行逻辑左移操作。将保存在寄存器 Rd 中的数据向左移动 Rm 所指定的次数移位的结果保存在寄存器 Rd 中,即:Rd=Rd<Rm。在左移过程中,最后移出去的位保存在寄存器 APSR 的Q标志中,也更新 N 和Z标志。
例如:
LSLS R0,R1
该指令将保存在寄存器 R0 中的数据向左移动 R1 所指定的次数,移位的结果保存在寄存器R0中。在左移过程中,最后移出去的位保存在寄存器 APSR 的 标志中,也更新 N 和Z标志
该指令执行逻辑左移操作。将保存在寄存器 Rd 中的数据向左移动立即数#immed5 所指定的次数(范围在 1~32 之间),移位的结果保存在寄存器 Rd 中,即:Rd=Rm<<#immed5。在左移过程中,最后移出去的位保存在寄存器 APSR的C标志中,也更新N和Z标志。
例如:
LSLS R0,R1,#0x01
该指令将保存在寄存器R1中的数据向左移动1次,移位的结果保存在寄存器R0中。在左移过程中,最后移出去的位保存在寄存器APSR的C标志中,也更新N和Z标志。
该指令将寄存器 Rm 中字节的顺序按逆序重新排列,结果保存在寄存器Rd中
例如:
REV R0,R1
该指令将寄存器中R1的数据逆序重新排列**{R1[7:0],R1[15:8],R1[23:16],R1[31:24]}**,结果保存在寄存器R0中。
该指令将寄存器 Rm 中的内容以半字为边界,半字内的两个字节逆序重新排列,结果保存在奇存器 Rd中
例如:
REV16 R0,R1
该指令将寄存器中R1的数据以半字为边界,半字内的字节按逆序重新排列,即**{R1[23:16],R1[31:24],R1[7:0],R1[15:8]}**,结果保存在寄存器R0中。
该指令将寄存器Rm中的低半字内的两个字节逆序重新排列,结果保存在寄存器Rd[15:0中,对于Rd[31:16]中的内容由交换字节后R[7]的内容决定,即符号扩展
例如:
REVSH R0,R1
该指令将寄存器中 R1 的低半字内的两个字节按逆序重新排列,结果保存在寄存器 R0[15:0]中,对于R0[31:16]中的内容由交换字节后 R0[7]的内容决定,即符号扩展,表示为:
RO=符号扩展{R1[7:0],R1[15:8]}
将寄存器 Rm 中的[7:0]进行符号扩展,结果保存在寄存器 Rd 中。
例如:
SXTB R0,R1
该指令将寄存器 R1中的[7:0]进行符号扩展,结果保存在寄存器R0中,表示为:
R0=符号扩展{R1[7:0]}
将寄存器 Rm 中的[15:0]进行符号扩展,结果保存在寄存器 Rd 中。
例如:
SXTH R0,R1
该指令将寄存器 R1中的[15:0]进行符号扩展,结果保存在寄存器 R0 中,表示为:
RO=符号扩展{R1[15:0]}
将寄存器 Rm 中的[7:0]进行零扩展,结果保存在寄存器 Rd 中。
UXTB R0,R1
该指令将寄存器 R1 中的[7:0]进行零扩展,结果保存在寄存器 R0 中,表示为:
R0=零扩展{R1[7:0]}
将寄存器 Rm 中的[15:0]进行零扩展,结果保存在寄存器 Rd 中。
例如:
UXTH R0,R1
该指令将奇存器 R1中的[15:0]进行零扩展,结果保存在寄存器 R0 中,表示为:
R0=零扩展{R1[15:0]}
该指令表示无条件跳转到label所标识的地址,跳转地址为当前PC 土 2046字节的范围内。
例如:
B loop
该指令实现无条件跳转到 loop 标识的地址。
有条件跳转指令,根据寄存器 APSR 中的 N、Z、C和V 标志,跳转到 label 所标识的地址。
例如:
BEQ loop
当寄存器 APSR 寄存器中的标志位Z为1时(EQ后缀表示等于,即Z=1),将 PC 值修改为 loop 标号所表示的地址值,也就是跳转到标号为 loop 的位置执行程序
具体条件的表示参考上面后缀舍义。
该指令表示跳转和链接,跳转到一个地址,并且将返回地址保存到寄存器 LR 中。跳转地址为当前 PC 士 16M 字节的范围内。该指令通常用于调用一个子程序或者函数。一旦完成了函数,通过执行指令“BX LR”可以返回。
例如:
BL functionA
该指令将PC值修改为 functionA 标号所表示的地址值,寄存器 LR 的值等于PC+4
该指令表示跳转和交换,跳转到寄存器所指定的地址,根据寄存器的第0位的值(1 表示Thumb,0表示ARM),在 ARM 和 Thumb 模式之间切换处理器的状态
例如:
BX R0
该指令将 PC值修改为 R0 寄存器内的内容,即PC=R0
跳转和带有交换的链接。跳转到寄存器所指定的地址,将返回地址保存到寄存器 LR 中,并且根据寄存器的第0位的值 (1表示 Thumb,0 表示ARM),在 ARM 和Thumb 模式之间切换处理器的状态。
例如:
BLX R0
该指令将 PC值修改为 R0 寄存器内的内容,即: PC=R0,并且寄存器 LR 的值等于 PC+4。
数据存储器屏蔽指令。在提交新的存储器访问之前,确保已经完成所有的存储器访问。
数据同步屏蔽指令。在执行下一条指令前,确保已经完成所有的存储器访问。
指令同步屏蔽指令。在执行新的指令前,刷新流水线,确保已经完成先前所有的指令。
管理员调用指令,触发 SVC 异常。
例如:
SVC #3
该指令表示触发SVC 异常,其参数为 3。
该指令修改处理器的状态,使能/禁止中断,该指令不会阻塞 NMI 和硬件故障句柄。
例如:
CPSIE 1 ;使能中断,清除 PRIMASK
CPSID 1 ;禁止中断,设置 PRIMASK
该指令等待中断,停止执行程序,直到中断到来或者处理器进入调试状态。
该指令等待事件,停止执行程序,直到事件到来(由内部事件寄存器设置)或者处理器进入调试状态。
在多处理环境 (包括自身) 中,向所有处理器发送事件。
该指令为空操作指令,该指令用于产生指令对齐,或者引入延迟。
该指令为断点指令,将处理器置位停止阶段。在该阶段,通过调试器,用户执行调试任务。由调试器插入 BKPT 指令,用于代替原来的指令。
immed8表示用于断点的标号,其范围为0x00~0xFF。
例如:
BKPT #0
该指令表示标号为0的断点。
该指令用于表示停止一个任务。在多线程系统中,使用该指令用于表示延迟当前线程(比如等待硬件),并且能被交换/唤出。在 Cortex-M3 中,作为NOP 执行,即表示与 NOP 一样。
《ARM Cortex-M0 全可编程SoC原理及实现》