ARM指令集概述
********************************************************
寄存器:
因为ARM有7种处理器模式,(用户usr、中断irq、快中断fiq、管理svc、中止abt、未定义und、系统sys),37个寄存器中是这样分的:
R0~R7是通用的,就是其中模式都可以用;
R8~R12分两组,就是有10个了,快中断模式用一组(R8_fiq~R12_fiq),其余的六种模式用一组(R8~R12);
R13、R14分六组,就是有12个,其中用户模式和系统模式共用一组(R13~R14),其余的5种模式各有一组【R13_irq~R14_irq】【R13_fiq~R14_fiq】【R13_svc~R14_svc】【R13_abt~R14_abt】【R13_und~R14_und】;
R15为七种模式共用;
程序状态寄存器:CPSR是共用的,SPSR也是分了组的,但是只有5个,因为在用户模式和系统模式下不需要SPSR。
所以ARM状态下每种模式是18个可用(用户模式和系统模式是17个)。
Thumb状态类推。因为Thumb状态下没有用到R8-R12寄存器。
********************************************************
在讲ARM指令集前,先讲下带条件指令的条件码的含义:
条件码:{cond}
条件指令影响程序状态字中的条件标志位。例如:BEQ指令(B指令包含EQ条件码)表示仅在Z标志位
置位时转跳。如果{cond}段为空则无条件执行指令。
指令描述如下:
2.6.1 跳转指令
跳转指令用于实 现程序流程的跳转,在ARM 程序中有两种方法可以实现程式流程的跳转:
透过向程序计数 器PC 写入跳转地址值,可以实现在4GB 的地址空间中的任意跳转,在跳转之前结合使用MOV LR,PC等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性26位地址空间的子程序使用。
ARM 指令集中的跳转指令可以完成从当前 指令向前或向后的32MB的地址空间的跳转,包括以下4 条指令:
B 指令是最简单的跳转指令。一旦遇到一个B 指令,ARM 处理器将立即跳转到给定的目标地 址,从那里继续执行。注意存储在跳转指令中的实际值是相对当前PC 值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻 址)。它是24 位有符号数,左移两位后有符号扩充为32 位,表示的有效偏移为26 位(前后32MB 的地址空间)。
BL 指令
BL 指令的语法为:
BL{条件} 目标地址
BL 是另一个跳转指令,但跳转之前,会在 寄存器R14 中保存PC 的当前内容,因此,可以透过将R14 的内容重新加载到PC 中,来返回到跳转指令之后的那个指令处执行。该指令是实现子程序使用的一个基本但常用的手段。以下指令:
BL Label ;当程序无条件跳转到标号Label 处执行时,同时将当前的PC 值保存到R14 中
BLX 指令
BLX 指令的语法为:
BLX 目标地址
BLX 指令从ARM 指令集跳转到指令中所指定的目标 地址,并将处理器的工作状态有ARM 状态切换到Thumb状态,该指令同时将PC 的当前内容保存到寄存器R14 中。因此,当子程序使用Thumb 指令集,而用户使用ARM 指令集时,可以透过BLX 指令实现子程序的使用和处理器工作状态的切换。同时,子程程序的返回可以透过将寄存器R14 值复制到PC 中来完成。
BX 指令
BX 指令的语法为:
BX{条件} 目标地址
BX 指令跳转到指令中所指定的目标地址, 目标地址处的指令既可以是ARM指令,也可以是Thumb 指令。
2.6.2 数据处理指令
数据处理指令可 分为数据传送指令、算术逻辑运算指令和比较指令等。数据传送指令用于在寄存器和内存之间进行数据的双向传输。算术逻辑运算指令完成常用的算术与逻辑的运 算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR 中的相应条件标志位。比较指令不保存运算结果,只更新CPSR中相应的条件标志位。1. MOV 指令
MOV 指令的语法为:
MOV{条件}{S} 目的寄存器,来源操作数
MOV 指令可完成从另一个寄存器、被移位 的寄存器或将一个立即数载入到目的寄存器。其中S 选项决定指令的操作是否影响CPSR 中条件标志位的值,当没有S 时指令不更新CPSR 中条件标志位的值。
指令范例:
MOV R1,R0 ;将寄存器R0 的值传送到寄存器R1
MOV PC,R14 ;将寄存器R14 的值传送到PC,常用于子程序返回
MOV R1,R0,LSL#3 ;将寄存器R0 的值左移3 位后传送到R1
2. MVN 指令
MVN 指令的语法为:
MVN{条件}{S} 目的寄存器,源操作数
MVN 指令可完成从另一个寄存器、被移位 的寄存器、或将一个立即数载入到目的寄存器。与MOV 指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到目的寄存器中。其中S 决定指令的操作是否影响CPSR 中条件标志位的值,当没有S 时指令不更新CPSR 中条件标志位的值。
指令范例:
MVN R0,#0 ;将立即数0 取反传送到寄存器R0 中,完成后R0=-1
3. CMP 指令
CMP 指令的语法为:
CMP{条件} 操作数1,操作数2
CMP 指令用于把一个寄存器的内容和另一 个寄存器的内容或立即数进行比较,同时更新CPSR 中条件标志位的值。该指令进行一次减法运算,但不存储结果,只更改条件标志位。标志位表示的是操作数1 与操作数2 的关系(大、小、相等),例如,当操作数1 大于操作操作数2,则此后的有GT 后缀的指令将可以执行。
指令范例:
CMP R1,R0 ;将寄存器R1 的值与寄存器R0 的值相减,并根据结果设定CPSR 的标志位
CMP R1,#100 ;将寄存器R1 的值与立即数100 相减,并根据结果设定CPSR 的标志位
4. CMN 指令
CMN 指令的语法为:
CMN{条件} 操作数1,操作数2
CMN 指令用于把一个寄存器的内容和另一 个寄存器的内容或立即数取反后进行比较,同时更新CPSR 中条件标志位的值。该指令实际完成操作数1 和运算元2 相加,并根据结果更改条件标志位。
指令范例:
CMN R1,R0 ;将寄存器R1 的值与寄存器R0 的值相加,并根据结果设定CPSR 的标志位
CMN R1,#100 ;将寄存器R1 的值与立即数100 相加,并根据结果设定CPSR 的标志位
5. TST 指令
TST 指令的语法为:
TST{条件} 操作数1,操作数2
TST 指令用于把一个寄存器的内容和另一 个寄存器的内容或立即数进行按位的与运算,并根据运算结果更新CPSR 中条件标志位的值。操作数1 是要测试的数据,而操作数2 是一个位屏蔽,该指令一般用来测试是 否设定了特定的位。
指令范例:30
TST R1,#%1 ;用于测试在寄存器R1 中是否设定了最低位(%表示二进制 数)
TST R1,#0xffe ;将寄存器R1 的值与立即数0xffe 按位与,并根据结果设定CPSR 的标志位
6. TEQ 指令
TEQ 指令的语法为:
TEQ{条件} 操作数1,操作数2
TEQ 指令用于把一个寄存器的内容和另一 个寄存器的内容或立即数进行按位的互斥运算,并根据运算结果更新CPSR 中条件标志位的值。该指令通常用于比较操作数1 和操作数2 是否相等。
指令范例:
TEQ R1,R2 ;将寄存器R1 的值与寄存器R2 的值按位互斥,并根据结果设定CPSR 的标志位
7. ADD 指令
ADD 指令的语法为:
ADD{条件}{S} 目的寄存器,操作数1,操作数2
ADD 指令用于把两个操作数相加,并将结 果存放到目的寄存器中。操作数1应是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器,或一个立即数。
指令范例:
ADD R0,R1,R2 ; R0 = R1 + R2
ADD R0,R1,#256 ; R0 = R1 + 256
ADD R0,R2,R3,LSL#1 ; R0 = R2 + (R3 << 1)
8. ADC 指令
ADC 指令的语法为:
ADC{条件}{S} 目的寄存器,操作数1,操作数2
ADC 指令用于把两个操作数相加,再加上CPSR 中的C 条件标志位的值,并将结果存放到目的 寄存器中。它使用一个进位标志位,这样就可以做比32 位大的数的加法,注意不要忘记设定S 后缀来更改进位标志。操作数1 应是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器,或一个立即数。以下指令序列完成两个128 位数的加法,第一个数由高到低存放 在寄存器R7-R4,第二个数由高到低存放在寄存器R11-R8,运算结果由高到低存放在寄存器R3-R0:
ADDS R0,R4,R8 ; 加低端的字
ADCS R1,R5,R9 ; 加第二个字,带进位
ADCS R2,R6,R10 ; 加第三个字,带进位
ADC R3,R7,R11 ; 加第四个字,带进位
9. SUB 指令
SUB 指令的语法为:
SUB {条件}{S} 目的寄存器,操作数1,操作数2
SUB 指令用于把操作数1 减去操作数2,并将结果存放到目的寄存器中。运算元1 应是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器, 或一个立即数。该指令可用于有符号数或无符号数的减法运算。
指令范例:
SUB R0,R1,R2 ; R0 = R1 - R2
SUB R0,R1,#256 ; R0 = R1 - 256
SUB R0,R2,R3,LSL#1 ; R0 = R2 - (R3 << 1)
10. SBC 指令
SBC 指令的语法为:
SBC{条件}{S} 目的寄存器,操作数1,操作数2
SBC 指令用于把操作数1 减去操作数2,再减去CPSR 中的C 条件标志位的反码,并将结果存放到目 的寄存器中。操作数1 应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于32 位的减法,注意不要忘记设定S 后缀来更改进位标志。该指令可用于有 符号数或无符号数的减法运算。
指令范例:
SUBS R0,R1,R2 ; R0 = R1 - R2 - !C,并根据结果设定CPSR 的进位标志位32
11. RSB 指令
RSB 指令的语法为:
RSB{条件}{S} 目的寄存器,操作数1,操作数2
RSB 指令称为逆向减法指令,用于把操作 数2 减去操作数1,并将结果存放到目的寄存器中。操作数1 应是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器,或一个立即数。该指令可用于有符号数或无符号数的减法运算。指令范例:
RSB R0,R1,R2 ; R0 = R2 – R1
RSB R0,R1,#256 ; R0 = 256 – R1
RSB R0,R2,R3,LSL#1 ; R0 = (R3 << 1) - R2
12. RSC 指令
RSC 指令的语法为:
RSC{条件}{S} 目的寄存器,操作数1,操作数2
RSC 指令用于把操作数2 减去操作数1,再减去CPSR 中的C 条件标志位的反码,并将结果存放到目 的寄存器中。操作数1 应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。该指令使用进位标志来表示借位,这样就可以做大于32 位的减法,注意不要忘记设定S 后缀来更改进位标志。该指令可用于有 符号数或无符号数的减法运算。
指令范例:
RSC R0,R1,R2 ; R0 = R2 – R1 - !C
13. AND 指令
AND 指令的语法为:
AND{条件}{S} 目的寄存器,操作数1,操作数2
AND 指令用于在两个操作数上进行逻辑与 运算,并把结果放置到目的寄存器中。操作数1 应是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于屏蔽操作数1 的某些位。
指令范例:33
AND R0,R0,#3 ; 该指令保持R0 的0、1 位,其余位清零。
14. ORR 指令
ORR 指令的语法为:
ORR{条件}{S} 目的寄存器,操作数1,操作数2
ORR 指令用于在两个操作数上进行逻辑或 运算,并把结果放置到目的寄存器中。操作数1 应是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于设定操作数1 的某些位。指令范例:
ORR R0,R0,#3 ; 该指令设定R0 的0、1 位,其余位保持不变。
15. EOR 指令
EOR 指令的语法为:
EOR{条件}{S} 目的寄存器,操作数1,操作数2
EOR 指令用于在两个操作数上进行逻辑互 斥运算,并把结果放置到目的寄存器中。操作数1 应是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器,或一个立即数。该指令常用于反转操作数1 的某些位。
指令范例:
EOR R0,R0,#3 ; 该指令反转R0 的0、1 位,其余位保持不变。
16. BIC 指令
BIC 指令的语法为:
BIC{条件}{S} 目的寄存器,操作数1,操作数2
BIC 指令用于清除操作数1 的某些位,并把结果放置到目的寄存器 中。运算元1 应是一个寄存器,操作数2 可以是一个寄存器,被移位的寄存器, 或一个立即数。操作数2 为32 位的屏蔽,如果在屏蔽中设定了某一位,则清除这一位。未设定的屏蔽位保持不变。指令范例:
BIC R0,R0,#%1011 ; 该指令清除R0 中的位0、1、和3,其余的位保持不变。
2.6.3 乘法指令与乘加指令
ARM 微处理器支持的乘法指令与乘加指令 共有6 条,可分为运算结果为32位和运算结果为64 位两类,与前面的数据处理指令不同,指令中的所有操作数、目的寄存器必须为通用寄存器,不能对操作数使用立即数或被移位的寄存器,同 时,目的寄存器和操作数1 必须是不同的寄存器。乘法指令与乘加指令共有以下6 条:
1. MUL 指令
MUL 指令的语法为:
MUL{条件}{S} 目的寄存器,操作数1,操作数2
MUL 指令完成将操作数1 与操作数2 的乘法运算,并把结果放置到目的寄存 器中,同时可以根据运算结果设定CPSR 中相应的条件标志位。其中,运算元1 和操作数2 均为32 位的有符号数或无符号数。
指令范例:
MUL R0,R1,R2 ;R0 = R1 × R2
MULS R0,R1,R2 ;R0 = R1 × R2,同时设定CPSR 中的相关条件标志位
2. MLA 指令
MLA 指令的语法为:
MLA{条件}{S} 目的寄存器,操作数1,操作数2,操作数3
MLA 指令完成将操作数1 与操作数2 的乘法运算,再将乘积加上操作数3并把结果放置到目的寄存器中,同时可以 根据运算结果设定CPSR 中相应的条件标志位。其中,操作数1 和操作数2 均为32 位的有符号数或无符号数。
指令范例:
MLA R0,R1,R2,R3 ;R0 = R1 × R2 + R3
MLAS R0,R1,R2,R3 ;R0 = R1 × R2 + R3,同时设定CPSR 中的相关条件标志位
3. SMULL 指令
SMULL 指令的语法为:
SMULL{条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2
SMULL 指令完成将操作数1 与操作数2 的乘法运算,并把结果的低32 位元放置到目的寄存器Low 中,结果的高32 位放置到目的寄存器High 中,同时可以根据运算结果设定CPSR 中相应的条件标志位。其中,操 作数1 和运算元2 均为32 位的有符号数。
指令范例:
SMULL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位;
4. 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 位。36
指令范例:
SMLAL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位+ R0
5. UMULL 指令
UMULL 指令的语法为:
UMULL {条件}{S} 目的寄存器Low,目的寄存器低High,操作数1,操作数2
UMULL 指令完成将操作数1 与操作数2 的乘法运算,并把结果的低32 位元放置到目的寄存器Low 中,结果的高32 位放置到目的寄存器High 中,同时可以根据运算结果设定CPSR 中相应的条件标志位。其中,操 作数1 和运算元2 均为32 位的无符号数。
指令范例:
UMULL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位
6. 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 位。
指令范例:
UMLAL R0,R1,R2,R3 ;R0 = (R2 × R3)的低32 位+ R0
2.6.4
ARM 微处理器支持程序状态寄存器存取指 令,用于在程序状态寄存器和通用寄存器之间传送数据,程序状态寄存器存取指令包括以下两条:
1. MRS 指令
MRS 指令的语法为:
MRS{条件} 通用寄存器,程序状态寄存器(CPSR 或SPSR)
MRS 指令用于将程序状态寄存器的内容传 送到通用寄存器中。该指令一般用在以下几种情况:
当需要改变程序 状态寄存器的内容时,可用MRS 将程序状态寄存器的内容读入通用寄存器,修改后再写回程序状态寄存器。
当在例外处理或 行程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。
指令范例:
MRS R0,CPSR ;传送CPSR 的内容到R0
MRS R0,SPSR ;传送SPSR 的内容到R0
2. MSR 指令
MSR 指令的语法为:
MSR{条件} 程序状态寄存器(CPSR 或SPSR)_<域>,操作数
MSR 指令用于将操作数的内容传送到程序 状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<域>用于设定程序状态寄存器中需要操作的位,32 位的程序状态寄存器可分为4 个域:
位[31:24]为条件标志位域,用f 表示;
位[23:16]为状态位域,用s 表示;38
位[15:8]为扩充位域,用x 表示;
位[7:0]为控制位域,用c 表示;
该指令通常用于 恢复或改变程序状态寄存器的内容,在使用时,一般要在MSR 指令中指明将要操作的域。
指令范例:
MSR CPSR,R0 ;传送R0 的内容到CPSR