ARM处理器的指令集能够分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令6大指令测试
1、跳转指令编码
跳转指令用于实现程序流程的跳转spa
跳转指令分类操作系统
Ⅰ.使用专门的跳转指令设计
分支指令 B3d
带连接的分支指令: BL调试
带状态切换的分支指令 BXblog
Ⅱ. 程序计数器PC控制进程
直接向程序计数器PC写入跳转地址值,经过向程序计数器PC写入跳转地址值
get
能够实如今4GB的地址空间中的任意跳转,在跳转以前结合使用MOV LR,PC等相似指令
能够保存未来的返回地址值,从而实如今4GB连续的线性地址空间的子程序调用。
ARM指令集中的跳转指令能够完成从当前指令向前或向后的32MB的地址空间的跳转,包括如下4条指令:
一、B指令
B指令的格式为:
B{条件} 目标地址
二、BL指令
BL指令的格式为:
BL{条件} 目标地址
BL是另外一个跳转指令,但跳转以前,会在寄存器R14中保存PC的当前内容,
所以,能够经过将R14的内容从新加载到PC中,来返回到跳转指令以后的那个 指令处执行。
该指令是实现子程序调用的一个基本但经常使用的手段
三、BLX指令
BLX指令的格式为:
BLX 目标地址
BLX指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工做状态有ARM状态切换到Thumb状态,
该指令同时将PC的当前内容保存到寄存器R14中。所以,当子程序使用Thumb指令集,而调用者使用ARM指令集时,
能够经过BLX指令实现子程序的调用和处理器工做状态的切换。同时,子程序的返回能够经过将寄存器R14值复制到PC中来完成
四、BX指令
BX指令的格式为:
BX{条件} 目标地址
BX指令跳转到指令中所指定的目标地址,目标地址处的指令既能够是ARM指令,也能够是Thumb指令。
2、数据处理指令
分类:
数据传送指令
数据传送指令用于在寄存器和存储器之间进行数据的双向传输
算术逻辑运算指令
算术逻辑运算指令完成经常使用的算术与逻辑的运算,该类指令影响CPSR中的相应条件标志位;
比较指令
比较指令不保存运算结果,只更新CPSR中相应的条件标志位
数据处理指令共如下16条:
一、MOV指令(传送)
MOV指令的格式为:
MOV{条件}{S} 目的寄存器,源操做数
MOV指令可完成从另外一个寄存器、被移位的寄存器或将一个当即数加载到目的寄存器。
其中S选项决定指令的操做是否影响CPSR中条件标志位的值,当没有S 时指令不更新CPSR中条件标志位的值
指令示例:
二、MVN指令(求反)
MVN指令的格式为:
MVN{条件}{S} 目的寄存器,源操做数
MVN指令可完成从另外一个寄存器、被移位的寄存器、或将一个当即数在传送以前按位被取反加载到目的寄存器。
其中S决定指令的操做是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。
指令示例:
三、CMP指令(比较)
CMP指令的格式为:
CMP{条件} 操做数1,操做数2
CMP指令用于把一个寄存器的内容和另外一个寄存器的内容或当即数进行比较,同时更新CPSR中条件标志位的值。
该指令进行一次减法运算,但不存储结果,只更改条件标志位。 标志位表示的是操做数1与操做数2的关系(大、小、相等),
例如,当操做数1大于操做操做数2,则此后的有GT后缀的指令将能够执行
指令示例:
四、CMN指令(负数比较)
CMN指令的格式为:
CMN{条件} 操做数1,操做数2
CMN指令用于把一个寄存器的内容和另外一个寄存器的内容或当即数取反后进行比较,
同时更新CPSR中条件标志位的值。该指令实际完成操做数1和操做数2相加,并根据结果更改条件标志位
指令示例:
五、TST指令(测试)
TST指令的格式为:
TST{条件} 操做数1,操做数2
TST指令用于把一个寄存器的内容和另外一个寄存器的内容或当即数进行按位的与运算
并根据运算结果更新CPSR中条件标志位的值。操做数1是要测试的数据,而操做数2是一个位掩码,该指令通常用来检测是否设置了特定的位。
指令示例:
六、TEQ指令(测试相等)
TEQ指令的格式为:
TEQ{条件} 操做数1,操做数2
TEQ指令用于把一个寄存器的内容和另外一个寄存器的内容或当即数进行按位的异或运算
并根据运算结果更新CPSR中条件标志位的值。该指令一般用于比较操做数1和操做数2是否相等
指令示例:
七、ADD指令(相加)
ADD指令的格式为:
ADD{条件}{S} 目的寄存器,操做数1,操做数2
ADD指令用于把两个操做数相加,并将结果存放到目的寄存器中操做数1应是一个寄存器,
操做数2能够是一个寄存器,被移位的寄存器,或一个当即数
指令示例:
八、ADC指令(带进位相加)
ADC指令的格式为:
ADC{条件}{S} 目的寄存器,操做数1,操做数2
ADC指令用于把两个操做数相加,再加上CPSR中的C条件标志位的值,并将结果存放到目的寄存器中。
它使用一个进位标志位,这样就能够作比32位大的数的加法,注意不要忘记设置S后缀来更改进位标志。
操做数1应是一个寄存器,操做数2能够是一个寄存器,被移位的寄存器,或一个当即数。
如下指令序列完成两个128位数的加法,第一个数由高到低存放在寄存器R7~R4,
第二个数由高到低存放在寄存器R11~R8,运算结果由高到低存放在寄存器R3~R0:
九、SUB指令(相减)
SUB指令的格式为:
SUB{条件}{S} 目的寄存器,操做数1,操做数2
SUB指令用于把操做数1减去操做数2,并将结果存放到目的寄存器中。
操做数1应是一个寄存器,操做数2能够是一个寄存器,被移位的寄存器,
或一个当即 数。该指令可用于有符号数或无符号数的减法运算
指令示例:
十、SBC指令
SBC指令的格式为:
SBC{条件}{S} 目的寄存器,操做数1,操做数2
SBC指令用于把操做数1减去操做数2,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。
操做数1应是一个寄存器,操做数2能够 是一个寄存器,被移位的寄存器,或一个当即数。
该指令使用进位标志来表示借位,这样就能够作大于32位的减法,
注意不要忘记设置S后缀来更改进位标志。该指令可用于有符号数或无符号数的减法运算。
指令示例:
十一、RSB指令
RSB指令的格式为:
RSB{条件}{S} 目的寄存器,操做数1,操做数2
RSB指令称为逆向减法指令,用于把操做数2减去操做数1,并将结果存放到目的寄存器中。
操做数1应是一个寄存器,操做数2能够是一个寄存器,被移位的寄存器,
或一个当即数。该指令可用于有符号数或无符号数的减法运算。
指令示例:
十二、RSC指令(反向带进位减)
RSC指令的格式为:
RSC{条件}{S} 目的寄存器,操做数1,操做数2
RSC指令用于把 操做数2减去操做数1,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。
操做数1应是一个寄存器,操做数2能够是一个寄存器,被移位的寄存器,或一个当即数。
该指令使用进位标志来表示借位,这样就能够作大于32位的减法,注意不要忘记设置S后缀来更改进位标志。
该指令可用于有符号数或 无符号数的减法运算
指令示例:
1三、AND指令(逻辑位 与)
AND指令的格式为:
AND{条件}{S} 目的寄存器,操做数1,操做数2
AND指令用于在两个操做数上进行逻辑与运算,并把结果放置到目的寄存器中。
操做数1应是一个寄存器,操做数2能够是一个寄存器,被移位的寄存器,
或一个当即数。该指令经常使用于屏蔽操做数1的某些位。
指令示例:
1四、ORR指令(逻辑位 或)
ORR指令的格式为:
ORR{条件}{S} 目的寄存器,操做数1,操做数2
ORR指令用于在两个操做数上进行逻辑或运算,并把结果放置到目的寄存器中。
操做数1应是一个寄存器,操做数2能够是一个寄存器,被移位的寄存器,
或一个当即数。该指令经常使用于设置操做数1的某些位
指令示例:
1五、EOR指令(逻辑位异或)
EOR指令的格式为:
EOR{条件}{S} 目的寄存器,操做数1,操做数2
EOR指令用于在两个操做数上进行逻辑异或运算,并把结果放置到目的寄存器中。
操做数1应是一个寄存器,操做数2能够是一个寄存器,被移位的寄存器,或一个当即数。该指令经常使用于反转操做数1的某些位
指令示例:
EOR R0,R0,#3 ;该指令反转R0的0、1位,其他位保持不变
1六、BIC指令(位清零)
BIC指令的格式为:
BIC{条件}{S} 目的寄存器,操做数1,操做数2
BIC指令用于清除操做数1的某些位,并把结果放置到目的寄存器中。
操做数1应是一个寄存器,操做数2能够是一个寄存器,被移位的寄存器,或一个当即数。
操做数2为32位的掩码,若是在掩码中设置了某一位,则清除这一位。未设置的掩码位保持不变
指令示例:
3、乘法指令与乘加指令
ARM 微处理器支持的乘法指令与乘加指令共有6条,可分为运算结果为32位和运算结果为64位两类,
与前面的数据处理指令不一样,指令中的全部操做数、目的寄存器 必须为通用寄存器,不能对操做数使用当即数或被移位的寄存器,
同时,目的寄存器和操做数1必须是不一样的寄存器。
乘法指令与乘加指令共有如下6条:
一、MUL指令(相乘)
MUL指令的格式为:
MUL{条件}{S} 目的寄存器,操做数1,操做数2
MUL指令完成将操做数1与操做数2的乘法运算,并把结果放置到目的寄存器中,
同时能够根据运算结果设置CPSR中相应的条件标志位。其中,操做数1和操 做数2均为32位的有符号数或无符号数。
指令示例:
二、MLA指令(带累加的相乘)
MLA指令的格式为:
MLA{条件}{S} 目的寄存器,操做数1,操做数2,操做数3
MLA指令完成将操做数1与操做数2的乘法运算,再将乘积加上操做数3,并把结果放置到目的寄存器中,
同时能够根据运算结果设置CPSR中相应的条件标志位。其中,操做数1和操做数2均为32位的有符号数或无符号数
指令示例:
三、SMULL指令
SMULL指令的格式为:
SMULL{条件}{S} 目的寄存器Low,目的寄存器High,操做数1,操做数2
SMULL指令完成将操做数1与操做数2的乘法运算,并把结果的低32位放置到目的寄存器Low中,
结果的高32位放置到目的寄存器High中,同时能够 根据运算结果设置CPSR中相应的条件标志位。
其中,操做数1和操做数2均为32位的有符号数
指令示例:
四、SMLAL指令
SMLAL指令的格式为:
SMLAL{条件}{S} 目的寄存器Low,目的寄存器High,操做数1,操做数2
SMLAL指令完成将操做数1与操做数2的乘法运算,并把结果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中
结果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,同时能够根据运算结果设置CPSR中相应的条件标志位。
其中,操做数1和操做数2均为32位的有符号数。
对于目的寄存器Low,在指令执行前存放64位加数的低32位,指令执行后存放结果的低32位;
对于目的寄存器High,在指令执行前存放64位加数的高32位,指令执行后存放结果的高32位。
指令示例:
五、UMULL指令
UMULL指令的格式为:
UMULL{条件}{S} 目的寄存器Low,目的寄存器High,操做数1,操做数2
UMULL指令完成将操做数1与操做数2的乘法运算,并把结果的低32位放置到目的寄存器Low中,
结果的高32位放置到目的寄存器High中,同时能够 根据运算结果设置CPSR中相应的条件标志位。
其中,操做数1和操做数2均为32位的无符号数
指令示例:
六、UMLAL指令
UMLAL指令的格式为:
UMLAL{条件}{S} 目的寄存器Low,目的寄存器High,操做数1,操做数2
UMLAL指令完成将操做数1与操做数2的乘法运算,并把结果的低32位同目的寄存器Low中的值相加后又放置到目的寄存器Low中,
结果的高32位同目的寄存器High中的值相加后又放置到目的寄存器High中,
同时能够根据运算结果设置CPSR中相应的条件标志位。其中,操做数1和操做数2均为32位的无符号数。
对于目的寄存器Low,在指令执行前存放64位加数的低32位,指令执行后存放结果的低32位;
对于目的寄存器High,在指令执行前存放64位加数的高32位,指令执行后存放结果的高32位。
指令示例:
4、程序状态寄存器访问指令
一、MRS指令
MRS指令的格式为:
MRS{条件} 通用寄存器 程序状态寄存器(CPSR或SPSR)
MRS指令用于将程序状态寄存器的内容传送到通用寄存器中。该指令通常用在如下两种状况:
Ⅰ.当须要改变程序状态寄存器的内容时,可用MRS将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。
Ⅱ.当在异常处理或进程切换时,须要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,而后保存
指令示例:
二、MSR指令
MSR指令的格式为:
MSR{条件} 程序状态寄存器(CPSR或SPSR)_<域>,操做数
MSR指令用于将操做数的内容传送到程序状态寄存器的特定域中。其中,操做数能够为通用寄存器或当即数。
<域>用于设置程序状态寄存器中须要操做的位,32位的程序状态寄存器可分为4个域:
位[31:24]为条件位域,用f表示;
位[23:16]为状态位域,用s表示;
位[15:8] 为扩展位域,用x表示;
位[7:0] 为控制位域,用c表示;
该指令一般用于恢复或改变程序状态寄存器的内容,在使用时,通常要在MSR指令中指明将要操做的域。
指令示例:
5、加载/存储指令
ARM微处理器支持加载/存储指令用于在寄存器和存储器之间传送数据,
加载指令用于将存储器中的数据传送到寄存器,存储 指令则完成相反的操做。经常使用的加载存储指令以下:
一、LDR指令
LDR指令的格式为:
LDR{条件} 目的寄存器,<存储器地址>
LDR指令用于从存储器中将一个32位的字数据传送到目的寄存器中。该指令一般用于从存储器中读取32位的字数据到通用寄存器
而后对数据进行处理。当程序计数器PC做为 目的寄存器时,指令从存储器中读取的字数据被看成目的地址,
从而能够实现程序流程的跳转。该指令在程序设计 中比较经常使用,且寻址方式灵活多样,请读者认真掌握。
指令示例:
二、LDRB指令
LDRB指令的格式为:
LDR{条件}B 目的寄存器,<存储器地址>
LDRB指令用于从存储器中将一个8位的字节数据传送到目的寄存器中,同时将寄存器的高24位清零。
该指令一般用于从存储器中读取8位的字节数据到通用寄存器,而后对数据进行处理。当程序计数器PC做为目的寄存器时,
指令从存储器中读取的字数据被看成目的地址,从而能够实现程序流程的跳转
指令示例:
三、LDRH指令
LDRH指令的格式为:
LDR{条件}H 目的寄存器,<存储器地址>
LDRH指令用于从存储器中将一个16位的半字数据传送到目的寄存器中,同时将寄存器的高16位清零。
该指令一般用于从存储器中读取16位的半字数据到通用寄存器,而后对数据进行处理。
当程序计数器PC做为目的寄存器时,指令从存储器中读取的字数据被看成目的地址,从而能够实现程序流程的跳转。
指令示例:
四、STR指令
STR指令的格式为:
STR{条件} 源寄存器,<存储器地址>
STR指令用于从源寄存器中将一个32位的字数据传送到存储器中。 该指令在程序设计中比较经常使用,
且寻址方式灵活多样,使用方式可参考指令LDR。
指令示例:
五、STRB指令
STRB指令的格式为:
STR{条件}B 源寄存器,<存储器地址>
STRB指令用于从源寄存器中将一个8位的字节数据传送到存储器中。该字节数据为源寄存器中的低8位
指令示例:
六、STRH指令
STRH指令的格式为:
STR{条件}H 源寄存器,<存储器地址>
STRH指令用于从源寄存器中将一个16位的半字数据传送到存储器中。该半字数据为源寄存器中的低16位。
指令示例:
6、批量数据加载/存储指令
ARM微处理器所支持批量数据加载/存储指令能够一次在一片连续的存储器单元和多个寄存器之间传送数据
批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令则完成相反的操做。
经常使用的加载存储指令以下:
LDM(或STM)指令
LDM(或STM){条件}{类型} 基址寄存器{!},寄存器列表{∧}
LDM(或STM)指令用于从由基址寄存器所指示的一片连续存储器到寄存器列表所指示的多个寄存器之间传送数据,
该指令的常见用途是将多个寄存器的内容入栈或出栈。
其中,{类型}为 如下几种状况:
IA 每次传送后地址加1;
IB 每次传送前地址加1;
DA 每次传送后地址减1;
DB 每次传送前地址减1;
FD 满递减堆栈;
ED 空递减堆栈;
FA 满递增堆栈;
EA 空递增堆栈;
{!}为可选后缀,若选用该后缀,则当数据 传送完毕以后,将最后的地址写入基址寄存器,
不然基址寄存器的内容不改变。基址寄存器不容许为R15,寄存器列表能够为R0~R15的任意组合。
{∧}为可选后缀,当指令为LDM且寄存器列表中包含R15,选用该后缀时表示:除了正常的数据传送以外,
还将SPSR复制到CPSR。同时,该后缀还表 示传入或传出的是用户模式下的寄存器,而不是当前模式下的寄存器。
指令示例:
7、数据交换指令
一、SWP指令
SWP指令的格式为:
SWP{条件} 目的寄存器,源寄存器1,[源寄存器2]
SWP指令用于将源寄存器2所指向的存储器中的字数据传送到目的寄存器中,同时将源寄存器1中的字数据传送到源寄存器2所指向的存储器中。
显然,当源寄存 器1和目的寄存器为同一个寄存器时,指令交换该寄存器和存储器的内容
指令示例:
二、SWPB指令
SWPB指令的格式为:
SWP{条件}B 目的寄存器,源寄存器1,[源寄存器2]
SWPB指令用于将源寄存器2所指向的存储器中的字节数据传送到目的寄存器中,目的寄存器的高24清零,
同时将源寄存 器1中的字节数据传送到源寄存器2所指向的存储器中。显然,当源寄存器1和目的寄存器为同一个寄存器时,
指令交换该寄存器和存储器的内容。
指令示例:
8、移位指令
一、LSL(或ASL)
LSL(或ASL)的格式为:
通用寄存器,LSL(或ASL) 操做数
LSL(或ASL)可完成对通用寄存器中的内容进行逻辑(或算术)的左移操做,按操做数所指定的数量向左移位,低位用零来填充。
其中,操做数能够是通用寄存器,也能够是当即数(0~31)
操做示例:
二、LSR
LSR的格式为:
通用寄存器,LSR 操做数
LSR可完成对通用寄存器中的内容进行右移的操做,按操做数所指定的数量向右移位,左端用零来填充。
其中,操做数能够 是通用寄存器,也能够是当即数(0~31)
操做示例:
三、ASR
ASR的格式为:
通用寄存器,ASR 操做数
ASR可完成对通用寄存器中的内容进行右移的操做,按操做数所指定的数量向右移位,左端用第31位的值来填充。
其中,操做数能够是通用寄存器,也能够是立 即数(0~31)。
操做示例:
四、ROR
ROR的格式为:
通用寄存器,ROR 操做数
ROR可完成对通用寄存器中的内容进行循环右移的操做,按操做数所指定的数量向右循环移位,左端用右端移出的位来填充。
其中,操做数能够是通用寄存器,也能够是当即数(0~31)。显然,当进行32位的循环右移操做时,通用寄存器中的值不改变。
操做示例:
五、RRX
RRX的格式为:
通用寄存器,RRX 操做数
RRX可完成对通用寄存器中的内容进行带扩展的循环右移的操做,按操做数所指定的数量向右循环移位,左端用进位标志位C来填充。
其中,操做数能够是通用寄 存器,也能够是当即数(0~31)。
操做示例:
9、协处理器指令
一、CDP指令
CDP指令的格式为:
CDP{条件} 协处理器编码,协处理器操做码1,目的寄存器,源寄存器1,源寄存器2,协处理器操做码2。
CDP指令用于ARM处理器通知ARM协处理器执行特定的操做,若协处理器不能成功完成特定的操做,
则产生未定义指令异常。其中协处理器操做码1和协处理 器操做码2为协处理器将要执行的操做,
目的寄存器和源寄存器均为协处理器的寄存器,指令不涉及ARM处理器的寄存器和存储器。
指令示例:
二、LDC指令
LDC指令的格式为:
LDC{条件}{L} 协处理器编码,目的寄存器,[源寄存器]
LDC指令用于将源寄存器所指向的存储器中的字数据传送到目的寄存器中,若协处理器不能成功完成传送操做,
则产生未定义指令异常。其中,{L}选项表示指 令为长读取操做,如用于双精度数据的传输
指令示例:
三、STC指令
STC指令的格式为:
STC{条件}{L} 协处理器编码,源寄存器,[目的寄存器]
STC指令用于将源寄存器中的字数据传送到目的寄存器所指向的存储器中,若协处理器不能成功完成传送操做,则产生未定义指令异常。
其中,{L}选项表示指 令为长读取操做,如用于双精度数据的传输
指令示例:
四、MCR指令
MCR指令的格式为:
MCR{条件} 协处理器编码,协处理器操做码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操做码2。
MCR指令用于将ARM处理器寄存器中的数据传送到协处理器寄存器中,若协处理器不能成功完成操做,
则产生未定义指令异常。其中协处理器操做码1和协处理 器操做码2为协处理器将要执行的操做,
源寄存器为ARM处理器的寄存器,目的寄存器1和目的寄存器2均为协处理器的寄 存器。
指令示例:
五、MRC指令
MRC指令的格式为:
MRC{条件} 协处理器编码,协处理器操做码1,目的寄存器,源寄存器1,源寄存器2,协处理器操做码2
MRC指令用于将协处理器寄存器中的数据传送到ARM处理器寄存器中,若协处理器不能成功完成操做,
则产生未定义指令异常。其中协处理器操做码1和协处理 器操做码2为协处理器将要执行的操做,
目的寄存器为ARM处理器的寄存器,源寄存器1和源寄存器2均为协处理器的寄存器。
指令示例:
10、异常产生指令
一、SWI指令
SWI指令的格式为:
SWI{条件} 24位的当即数
SWI指令用于产生软件中断,以便用户程序能调用操做系统的系统例程。操做系统在SWI的异常处理程序中提供相应的系统服务,
指令中24位的当即数指定用 户程序调用系统例程的类型,相关参数经过通用寄存器传递,当指令中24位的当即数被忽略时,
用户程序调用系统例程的类型由通用寄存器R0的内容决定,同 时,参数经过其余通用寄存器传递
指令示例:
二、BKPT指令
BKPT指令的格式为:
BKPT 16位的当即数
BKPT指令产生软件断点中断,可用于程序的调试