ARM
指令集概述
2010-04-18
本章节对ARM
指令集的六大类
指令进行详细的描述。
在讲ARM
指令集前,先讲下带条件
指令的条件码的含义:
条件码:{cond}
大部分ARM
指令和Thumb分支
指令包含一个条件码字段。该字段在
指令中用{cond}标示。
条件
指令影响程序状态字中的条件标志位。例如:BEQ
指令(B
指令包含EQ条件码)表示仅在Z标志位
置位时转跳。如果{cond}段为空则无条件执行
指令。
指令描述如下:
{cond}后缀 测试状态位 描述 EQ Z置位 相等 NE Z清零 不相等 CS/HS C置位 无符号数大于或等于 CC/LO C清零 无符号数小于 MI N置位 负数 PL N清零 正数或0 VS V置位 溢出 VC V清零 没有溢出 HI C置位,Z清零 无符号数大于 LS C清零,Z置位 无符号数小于或等于 GE N等于V 带符号数大于或等于 LT N不等于V 带符号数小于 GT Z清零,(N等于V) 带符号数大于 LE Z置位或(N不等于V) 带符号数小于或等于 AL 任何 无条件执行(
指令默认条件)
2.6.1 跳转
指令 跳转
指令用于实 现程序流程的跳转,在ARM 程序中有两种方法可以实现程式流程的跳转:
使用专门的跳转
指令。
直接向程序计数器PC 写入跳转地址值。
透过向程序计数 器PC 写入跳转地址值,可以实现在4GB 的地址空间中的任意跳转,在跳转之前结合使用MOV LR,PC等类似
指令,可以保存将来的返回地址值,从而实现在4GB连续的线性26位地址空间的子程序使用。
ARM
指令集中的跳转
指令可以完成从当前
指令向前或向后的32MB的地址空间的跳转,包括以下4 条
指令:
B 跳转
指令。
BL 带返回的跳转
指令。
BLX 带返回和状态切换的跳转
指令。
BX 带状态切换的跳转
指令。
B
指令 B
指令的语法为:
B {条件}目标地址
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 条:
MUL 32 位乘法
指令 MLA 32 位乘加
指令 SMULL 64 位有符号数乘法
指令 SMLAL 64 位有符号数乘加
指令 UMULL 64 位无符号数乘法
指令 UMLAL 64 位无符号数乘加
指令 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 位;
;R1 = (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
;R1 = (R2 × R3)的高32 位+ R1
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 位
;R1 = (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
;R1 = (R2 × R3)的高32 位+ R137
2.6.4 程序状态寄存器存取
指令 ARM 微处理器支持程序状态寄存器存取指 令,用于在程序状态寄存器和通用寄存器之间传送数据,程序状态寄存器存取
指令包括以下两条:
MRS 程序状态寄存器到通用寄存器的数据传送
指令。
MSR 通用寄存器到程序状态寄存器的数据传送
指令。
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
MSR SPSR,R0 ;传送R0 的内容到SPSR
MSR CPSR_c,R0 ;传送R0 的内容到SPSR,但仅仅修改CPSR 中的控制位域