本章介
绍
ARM
指令集、
Thumb
指令集,以及各
类
指令
对应
的
寻
址方式,通
过对
本章的
阅读
,希望
读
者能了解
ARM
微
处
理器所支持的指令集及具体的使用方法。
本章的主要内容有:
-
ARM
指令集、
Thumb
指令集概述。
-
ARM
指令集的分
类
与具体
应
用。
-
Thumb
指令集
简
介及
应
用
场
合。
3.1 ARM 微 处 理器的指令集概述
3.1.1 A RM 微 处 理器的指令的分 类 与格式
3.1 ARM 微 处 理器的指令集概述
3.1.1 A RM 微 处 理器的指令的分 类 与格式
ARM
微
处
理器的指令
集是加
载
/
存
储
型的,
也
即指令集
仅
能
处
理寄存器中的数据
,而且
处
理
结
果都要放回寄存器中,而
对
系
统
存
储
器的
访问则
需要通
过专门
的加
载
/
存
储
指令来完成。
ARM
微
处
理器的指令集可以分
为
跳
转
指令、数据
处
理指令、程序状
态
寄存器(
PSR
)
处
理指令、加
载
/
存
储
指令、
协处
理器指令和异常
产
生指令六大
类
,具体的指令及功能如表
3-1
所示(表中指令
为
基本
ARM
指令,不包括派生的
ARM
指令)。
表
3-1 ARM
指令及功能描述
助记符
|
指令功能描述
|
ADC
|
带进位加法指令
|
ADD
|
加法指令
|
AND
|
逻辑与指令
|
B
|
跳转指令
|
BIC
|
位清零指令
|
BL
|
带返回的跳转指令
|
BLX
|
带返回和状态切换的跳转指令
|
BX
|
带状态切换的跳转指令
|
CDP
|
协处理器数据操作指令
|
CMN
|
比较反值指令
|
CMP
|
比较指令
|
EOR
|
异或指令
|
LDC
|
存储器到协处理器的数据传输指令
|
LDM
|
加载多个寄存器指令
|
LDR
|
存储器到寄存器的数据传输指令
|
MCR
|
从
ARM
寄存器到协处理器寄存器的数据传输指令
|
MLA
|
乘加运算指令
|
MOV
|
数据传送指令
|
MRC
|
从协处理器寄存器到
ARM
寄存器的数据传输指令
|
MRS
|
传送
CPSR
或
SPSR
的内容到通用寄存器指令
|
MSR
|
传送通用寄存器到
CPSR
或
SPSR
的指令
|
MUL
|
32
位乘法指令
|
MLA
|
32
位乘加指令
|
MVN
|
数据取反传送指令
|
ORR
|
逻辑或指令
|
RSB
|
逆向减法指令
|
RSC
|
带借位的逆向减法指令
|
SBC
|
带借位减法指令
|
STC
|
协处理器寄存器写入存储器指令
|
STM
|
批量内存字写入指令
|
STR
|
寄存器到存储器的数据传输指令
|
SUB
|
减法指令
|
SWI
|
软件中断指令
|
SWP
|
交换指令
|
TEQ
|
相等测试指令
|
TST
|
位测试指令
|
3.1.2 指令的条件域
当
处
理器工作在
ARM
状
态时
,几乎所有的指令均根据
CPSR
中条件
码
的状
态
和指令的条件域有条件的
执
行
。当指令的
执
行条件
满
足
时
,指令被
执
行,否
则
指令被忽略。
每
一条
ARM
指令包含
4
位的条件
码
,位于指令的最高
4
位
[31:28]
。条件
码
共有
16
种
,
每种
条件
码
可用两个字符表示,
这
两个字符可以添加在指令助
记
符的后面和指令同
时
使用。例如,跳
转
指令
B
可以加上后
缀
EQ
变为
BEQ
表示
“
相等
则
跳
转
”
,即当
CPSR
中的
Z
标
志置位
时发
生跳
转
。
在
16
种
条件
标
志
码
中,只有
15
种
可以使用,如表
3-2
所示,第
16
种
(
1111
)
为
系
统
保留,
暂时
不能使用。
表
3-2
指令的条件
码
条件码
|
助记符后缀
|
标
志
|
含
义
|
0000
|
EQ
|
Z
置位
|
相等
|
0001
|
NE
|
Z
清零
|
不相等
|
0010
|
CS
|
C
置位
|
无符号数大于或等于
|
0011
|
CC
|
C
清零
|
无符号数小于
|
0100
|
MI
|
N
置位
|
负数
|
0101
|
PL
|
N
清零
|
正数或零
|
0110
|
VS
|
V
置位
|
溢出
|
0111
|
VC
|
V
清零
|
未溢出
|
1000
|
HI
|
C
置位
Z
清零
|
无符号数大于
|
1001
|
LS
|
C
清零
Z
置位
|
无符号数小于或等于
|
1010
|
GE
|
N
等于
V
|
带符号数大于或等于
|
1011
|
LT
|
N
不等于
V
|
带符号数小于
|
1100
|
GT
|
Z
清零且(
N
等于
V
)
|
带符号数大于
|
1101
|
LE
|
Z
置位或(
N
不等于
V
)
|
带符号数小于或等于
|
1110
|
AL
|
忽略
|
无条件执行
|
3.2 ARM 指令的 寻 址方式
所
谓寻
址方式就是
处
理器根据指令中
给
出的地址信息来
寻
找物理地址的方式。目前
ARM
指令系
统
支持如下几
种
常
见
的
寻
址方式。
3.2.1 立即 寻 址
3.2.1 立即 寻 址
立即
寻
址也叫立即数
寻
址,
这
是一
种
特殊的
寻
址方式,操作数本身就在指令中
给
出,只要取出指令也就取到了操作数。
这
个操作数被称
为
立即数,
对应
的
寻
址方式也就叫做立即
寻
址。例如以下指令:
ADD R0
,
R0
,#
1
;
R0←R0
+
1
ADD R0
,
R0
,#
0x3f
;
R0←R0
+
0x3f
在以上两条指令中,第二个源操作数即
为
立即数,要求以
“
#
”
为
前
缀
,
对
于以十六
进
制表示的立即数,
还
要求在
“
#
”
后加上
“0x”
或
“&”
。
3.2.2 寄存器 寻 址
3.2.2 寄存器 寻 址
寄存器
寻
址就是利用寄存器中的数
值
作
为
操作数,
这种寻
址方式是各
类
微
处
理器
经
常采用的一
种
方式,也是一
种执
行效率
较
高的
寻
址方式。以下指令:
ADD R0
,
R1
,
R2
;
R0←R1
+
R2
该
指令的
执
行效果是将寄存器
R1
和
R2
的内容相加,其
结
果存放在寄存器
R0
中。
3.2.2 寄存器 间 接 寻 址
3.2.2 寄存器 间 接 寻 址
寄存器
间
接
寻
址就是以寄存器中的
值
作
为
操作数的地址,而操作数本身存放在存
储
器中。例如以下指令:
ADD R0
,
R1
,
[R2]
;
R0←R1
+
[R2]
LDR R0
,
[R1]
;
R0←[R1]
STR R0
,
[R1]
;
[R1]←R0
在第一条指令中,以寄存器
R2
的
值
作
为
操作数的地址,在存
储
器中取得一个操作数后与
R1
相加,
结
果存入寄存器
R0
中。
第二条指令将以
R1
的
值为
地址的存
储
器中的数据
传
送到
R0
中。
第三条指令将
R0
的
值传
送到以
R1
的
值为
地址的存
储
器中。
3.2.3 基址 变 址 寻 址
3.2.3 基址 变 址 寻 址
基址
变
址
寻
址就是将寄存器(
该
寄存器一般称作基址寄存器)的内容与指令中
给
出的地址偏移量相加,从而得到一个操作数的有效地址。
变
址
寻
址方式常用于
访问
某基地址附近的地址
单
元。采用
变
址
寻
址方式的指令常
见
有以下几
种
形式,如下所示:
LDR R0
,
[R1
,#
4]
;
R0←[R1
+
4]
LDR R0
,
[R1
,#
4]
!
;
R0←[R1
+
4]
、
R1←R1
+
4
LDR R0
,
[R1]
,#
4
;
R0←[R1]
、
R1←R1
+
4
LDR R0
,
[R1
,
R2]
;
R0←[R1
+
R2]
在第一条指令中,将寄存器
R1
的内容加上
4
形成操作数的有效地址,从而取得操作数存入寄存器
R0
中。
在第二条指令中,将寄存器
R1
的内容加上
4
形成操作数的有效地址,从而取得操作数存入寄存器
R0
中,然后,
R1
的内容自增
4
个字
节
。
在第三条指令中,以寄存器
R1
的内容作
为
操作数的有效地址,从而取得操作数存入寄存器
R0
中,然后,
R1
的内容自增
4
个字
节
。
在第四条指令中,将寄存器
R1
的内容加上寄存器
R2
的内容形成操作数的有效地址,从而取得操作数存入寄存器
R0
中。
3.2.4 多寄存器 寻 址
3.2.4 多寄存器 寻 址
采用多寄存器
寻
址方式,一条指令可以完成多个寄存器
值
的
传
送。
这种寻
址方式可以用一条指令
完成
传
送最多
16
个通用寄存器的
值
。以下指令:
LDMIA R0
,
{R1
,
R2
,
R3
,
R4}
;
R1←[R0]
;
R2←[R0
+
4]
;
R3←[R0
+
8]
;
R4←[R0
+
12]
该
指令的后
缀
IA
表示在
每
次
执
行完加
载
/
存
储
操作后,
R0
按字
长
度增加,因此,指令可将
连续
存
储单
元的
值传
送到
R1
~
R4
。
3.2.5 相 对寻 址
3.2.5 相 对寻 址
与基址
变
址
寻
址方式相
类
似,相
对寻
址以程序
计
数器
PC
的当前
值为
基地址,指令中的地址
标
号作
为
偏移量,将两者相加之后得到操作数的有效地址。以下程序段完成子程序的
调
用和返回,跳
转
指令
BL
采用了相
对寻
址方
式:
BL NEXT
;跳
转
到子程序
NEXT
处执
行
……
NEXT
……
MOV PC
,
LR
;从子程序返回
3.2.6 堆 栈寻 址
3.2.6 堆 栈寻 址
堆
栈
是一
种
数据
结
构,按先
进
后出(
First In Last Out
,
FILO
)的方式工作,使用一个称作堆
栈
指
针
的
专
用寄存器指示当前的操作位置,堆
栈
指
针总
是指向
栈顶
。
当堆
栈
指
针
指向最后
压
入堆
栈
的数据
时
,称
为满
堆
栈
(
Full Stack
),而当堆
栈
指
针
指向下一个将要放入数据的空位置
时
,称
为
空堆
栈
(
Empty Stack
)。
同
时
,根据堆
栈
的生成方式,又可以分
为递
增堆
栈
(
Ascending Stack
)和
递
减堆
栈
(
Decending Stack
),当堆
栈
由低地址向高地址生成
时
,称
为递
增堆
栈
,当堆
栈
由高地址向低地址生成
时
,称
为递
减堆
栈
。
这样
就有四
种类
型的堆
栈
工作方式,
ARM
微
处
理器支持
这
四
种类
型的堆
栈
工作方式,即:
-
满递
增堆
栈
:堆
栈
指
针
指向最后
压
入的数据,且由低地址向高地址生成。
-
满递
减堆
栈
:堆
栈
指
针
指向最后
压
入的数据,且由高地址向低地址生成。
-
空
递
增堆
栈
:堆
栈
指
针
指向下一个将要放入数据的空位置,且由低地址向高地址生成。
-
空
递
减堆
栈
:堆
栈
指
针
指向下一个将要放入数据的空位置,且由高地址向低地址生成。
3.3 ARM 指令集
3.3 ARM 指令集
本
节对
ARM
指令集的六大
类
指令
进
行
详细
的描述。
3.3.1 跳 转 指令
3.3.1 跳 转 指令
跳
转
指令用于
实现
程序流程的跳
转
,在
ARM
程序中有两
种
方法可以
实现
程序流程的跳
转
:
—
使用
专门
的跳
转
指令。
—
直接向程序
计
数器
PC
写入跳
转
地址
值
。
通
过
向程序
计
数器
PC
写入跳
转
地址
值
,可以
实现
在
4GB
的地址空
间
中的任意跳
转
,在跳
转
之前
结
合使用
MOV LR
,
PC
等
类
似指令,可以保存将来的返回地址
值
,从而
实现
在
4GB
连续
的
线
性地址空
间
的子程序
调
用。
ARM
指令集中的跳
转
指令可以完成从当前指令向前或向后的
32MB
的地址空
间
的跳
转
,包括以下
4
条指令:
— B
跳
转
指令
— BL
带
返回的跳
转
指令
— BLX
带
返回和状
态
切
换
的跳
转
指令
— BX
带
状
态
切
换
的跳
转
指令
1
、
B
指令
B
指令的格式
为
:
B{
条件
}
目
标
地址
B
指令是最
简单
的跳
转
指令。一旦遇到一个
B
指令,
ARM
处
理器将立即跳
转
到
给
定的目
标
地址,从那里
继续执
行。注意存
储
在跳
转
指令中的
实际值
是相
对
当前
PC
值
的一个偏移量,而不是一个
绝对
地址,它的
值
由
汇编
器来
计
算(参考
寻
址方式中的
相
对寻
址)。它是
24
位有符号数,左移两位后有符号
扩
展
为
32
位,表示的有效偏移
为
26
位
(
前后
32MB
的地址空
间
)
。以下指令:
B Label
;程序无条件跳
转
到
标
号
Label
处执
行
CMP R1
,#
0
;当
CPSR
寄存器中的
Z
条件
码
置位
时
,程序跳
转
到
标
号
Label
处执
行
BEQ Label
2
、
BL
指令
BL
指令的格式
为
:
BL{
条件
}
目
标
地址
BL
是另一个跳
转
指令,但跳
转
之前,会在寄存器
R14
中保存
PC
的当前内容,因此,可以通
过
将
R14
的内容重新加
载
到
PC
中,来返回到跳
转
指令之后的那个
指令
处执
行。
该
指令是
实现
子程序
调
用的一个基本但常用的手段。以下指令:
BL Label
;当程序无条件跳
转
到
标
号
Label
处执
行
时
,同
时
将当前的
PC
值
保存到
R14
中
3
、
BLX
指令
BLX
指令的格式
为
:
BLX
目
标
地址
BLX
指令从
ARM
指令集跳
转
到指令中所指定的目
标
地址,并将
处
理器的工作状
态
有
ARM
状
态
切
换
到
Thumb
状
态
,
该
指令同
时
将
PC
的当前内容保存到寄存器
R14
中。因此,当子程序使用
Thumb
指令集,而
调
用者使用
ARM
指令集
时
,可以通
过
BLX
指令
实现
子程序的
调
用和
处
理器工作状
态
的切
换
。同
时
,子程序的返回可以通
过
将寄存器
R14
值复
制到
PC
中来完成。
4
、
BX
指令
BX
指令的格式
为
:
BX{
条件
}
目
标
地址
BX
指令跳
转
到指令中所指定的目
标
地址,目
标
地址
处
的指令既可以是
ARM
指令,也可以是
Thumb
指令。
3.3.2 数据 处 理指令
数据
处
理指令可分
为
数据
传
送指令、算
术逻辑
运算指令和比
较
指令等。
数据
传
送指令用于在寄存器和存
储
器之
间进
行数据的双向
传输
。
算
术逻辑
运算指令完成常用的算
术
与
逻辑
的运算,
该类
指令不但将运算
结
果保存在目的寄存器中,同
时
更新
CPSR
中的相
应
条件
标
志位。
比
较
指令不保存运算
结
果,只更新
CPSR
中相
应
的条件
标
志位。
数据
处
理指令包括:
— MOV
数据
传
送指令
— MVN
数据取反
传
送指令
— CMP
比
较
指令
— CMN
反
值
比
较
指令
— TST
位
测试
指令
— TEQ
相等
测试
指令
— ADD
加法指令
— ADC
带进
位加法指令
— SUB
减法指令
— SBC
带
借位减法指令
— RSB
逆向减法指令
— RSC
带
借位的逆向减法指令
— AND
逻辑
与指令
— ORR
逻辑
或指令
— EOR
逻辑
异或指令
— BIC
位清除指令
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
是一个位掩
码
,
该
指令一般用来
检测
是否
设
置了特定的位。
指令示例:
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
的
进
位
标
志位
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
的某些位。
指令示例:
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
,其余的位保持不
变
。
3.3.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
位。
指令示例:
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
位
+
R1
3.3.4 程序状 态 寄存器 访问 指令
3.3.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
表示;
位
[15
:
8]
为扩
展位域,用
x
表示;
位
[7
:
0]
为
控制位域,用
c
表示;
该
指令通常用于恢
复
或改
变
程序状
态
寄存器的内容,在使用
时
,一般要在
MSR
指令中指明将要操作的域。
指令示例:
MSR CPSR
,
R0
;
传
送
R0
的内容到
CPSR
MSR SPSR
,
R0
;
传
送
R0
的内容到
SPSR
MSR CPSR_c
,
R0
;
传
送
R0
的内容到
SPSR
,但
仅仅
修改
CPSR
中的控制位域
3.3.5 加 载 / 存 储 指令
ARM
微
处
理器支持加
载
/
存
储
指令用于在寄存器和存
储
器之
间传
送数据,加
载
指令用于将存
储
器中的数据
传
送到寄存器,存
储
指令
则
完成相反的操作。常用的加
载
存
储
指令如下:
— LDR
字数据加
载
指令
— LDRB
字
节
数据加
载
指令
— LDRH
半字数据加
载
指令
— STR
字数据存
储
指令
— STRB
字
节
数据存
储
指令
— STRH
半字数据存
储
指令
1
、
LDR
指令
LDR
指令的格式
为
:
LDR{
条件
}
目的寄存器,
<
存
储
器地址
>
LDR
指令用于从存
储
器中将一个
32
位的字数据
传
送到目的寄存器中。
该
指令通常用于从存
储
器中
读
取
32
位的字数据到通用寄存器,然后
对
数据
进
行
处
理。当程序
计
数器
PC
作
为
目的寄存器
时
,指令从存
储
器中
读
取的字数据被当作目的地址,从而可以
实现
程序流程的跳
转
。
该
指令在程序
设计
中比
较
常用,且
寻
址方式灵活多
样
,
请读
者
认
真掌握。
指令示例:
LDR R0
,
[R1]
;将存
储
器地址
为
R1
的字数据
读
入寄存器
R0
。
LDR R0
,
[R1
,
R2]
;将存
储
器地址
为
R1+R2
的字数据
读
入寄存器
R0
。
LDR R0
,
[R1
,#
8]
;将存
储
器地址
为
R1+8
的字数据
读
入寄存器
R0
。
LDR R0
,
[R1
,
R2]
!
;将存
储
器地址
为
R1+R2
的字数据
读
入寄存器
R0
,并将新地址
R1
+
R2
写入
R1
。
LDR R0
,
[R1
,#
8]
!
;将存
储
器地址
为
R1+8
的字数据
读
入寄存器
R0
,并将新地址
R1
+
8
写入
R1
。
LDR R0
,
[R1]
,
R2
;将存
储
器地址
为
R1
的字数据
读
入寄存器
R0
,并将新地址
R1
+
R2
写入
R1
。
LDR R0
,
[R1
,
R2
,
LSL
#
2]
!
;将存
储
器地址
为
R1
+
R2×4
的字数据
读
入寄存器
R0
,并将新地址
R1
+
R2×4
写入
R1
。
LDR R0
,
[R1]
,
R2
,
LSL
#
2
;将存
储
器地址
为
R1
的字数据
读
入寄存器
R0
,并将新地址
R1
+
R2×4
写入
R1
。
2
、
LDRB
指令
LDRB
指令的格式
为
:
LDR{
条件
}B
目的寄存器,
<
存
储
器地址
>
LDRB
指令用于从存
储
器中将一个
8
位的字
节
数据
传
送到目的寄存器中,同
时
将寄存器的高
24
位清零。
该
指令通常用于从存
储
器中
读
取
8
位的字
节
数据到通用寄存器,然后
对
数据
进
行
处
理。当程序
计
数器
PC
作
为
目的寄存器
时
,指令从存
储
器中
读
取的字数据被当作目的地址,从而可以
实现
程序流程的跳
转
。
指令示例:
LDRB R0
,
[R1]
;将存
储
器地址
为
R1
的字
节
数据
读
入寄存器
R0
,并将
R0
的高
24
位清零。
LDRB R0
,
[R1
,#
8]
;将存
储
器地址
为
R1
+
8
的字
节
数据
读
入寄存器
R0
,并将
R0
的高
24
位清零。
3
、
LDRH
指令
LDRH
指令的格式
为
:
LDR{
条件
}H
目的寄存器,
<
存
储
器地址
>
LDRH
指令用于从存
储
器中将一个
16
位的半字数据
传
送到目的寄存器中,同
时
将寄存器的高
16
位清零。
该
指令通常用于从存
储
器中
读
取
16
位的半字数据到通用寄存器,然后
对
数据
进
行
处
理。当程序
计
数器
PC
作
为
目的寄存器
时
,指令从存
储
器中
读
取的字数据
被当作目的地址,从而可以
实现
程序流程的跳
转
。
指令示例:
LDRH R0
,
[R1]
;将存
储
器地址
为
R1
的半字数据
读
入寄存器
R0
,并将
R0
的高
16
位清零。
LDRH R0
,
[R1
,#
8]
;将存
储
器地址
为
R1
+
8
的半字数据
读
入寄存器
R0
,并将
R0
的高
16
位清零。
LDRH R0
,
[R1
,
R2]
;将存
储
器地址
为
R1
+
R2
的半字数据
读
入寄存器
R0
,并将
R0
的高
16
位清零。
4
、
STR
指令
STR
指令的格式
为
:
STR{
条件
}
源寄存器,
<
存
储
器地址
>
STR
指令用于从源寄存器中将一个
32
位的字数据
传
送到存
储
器中。
该
指令在程序
设计
中比
较
常用,且
寻
址方式灵活多
样
,使用方式可参考指令
LDR
。
指令示例:
STR R0
,
[R1]
,#
8
;将
R0
中的字数据写入以
R1
为
地址的存
储
器中,并将新地址
R1
+
8
写入
R1
。
STR R0
,
[R1
,#
8]
;将
R0
中的字数据写入以
R1
+
8
为
地址的存
储
器中。
5
、
STRB
指令
STRB
指令的格式
为
:
STR{
条件
}B
源寄存器,
<
存
储
器地址
>
STRB
指令用于从源寄存器中将一个
8
位的字
节
数据
传
送到存
储
器中。
该
字
节
数据
为
源寄存器中的
低
8
位。
指令示例:
STRB R0
,
[R1]
;将寄存器
R0
中的字
节
数据写入以
R1
为
地址的存
储
器中。
STRB R0
,
[R1
,#
8]
;将寄存器
R0
中的字
节
数据写入以
R1
+
8
为
地址的存
储
器中。
6
、
STRH
指令
STRH
指令的格式
为
:
STR{
条件
}H
源寄存器,
<
存
储
器地址
>
STRH
指令用于从源寄存器中将一个
16
位的半字数据
传
送到存
储
器中。
该
半字数据
为
源寄存器中的低
16
位。
指令示例:
STRH R0
,
[R1]
;将寄存器
R0
中的半字数据写入以
R1
为
地址的存
储
器中。
STRH R0
,
[R1
,#
8]
;将寄存器
R0
中的半字数据写入以
R1
+
8
为
地址的存
储
器中。
3.3.6
批量数据加
载
/
存
储
指令
ARM
微
处
理器所支持批量数据加
载
/
存
储
指令可以一次在一片
连续
的存
储
器
单
元和多个寄存器之
间传
送数据,批量加
载
指令用于将一片
连续
的存
储
器中的数据
传
送到多个寄存器,批量数据存
储
指令
则
完成相反的操作。常用的加
载
存
储
指令如下:
— LDM
批量数据加
载
指令
— STM
批量数据存
储
指令
LDM
(或
STM
)指令
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
。同
时
,
该
后
缀还
表示
传
入或
传
出的是用
户
模式下的寄存器,而不是当前模式下的寄存器。
指令示例:
STMFD R13!
,
{R0
,
R4-R12
,
LR}
;将寄存器列表中的寄存器(
R0
,
R4
到
R12
,
LR
)存入堆
栈
。
LDMFD R13!
,
{R0
,
R4-R12
,
PC}
;将堆
栈
内容恢
复
到寄存器(
R0
,
R4
到
R12
,
LR
)。
3.3.7 数据交 换 指令
ARM
微
处
理器所支持数据交
换
指令能在存
储
器和寄存器之
间
交
换
数据。数据交
换
指令有如下两条:
— SWP
字数据交
换
指令
— SWPB
字
节
数据交
换
指令
1
、
SWP
指令
SWP
指令的格式
为
:
SWP{
条件
}
目的寄存器,源寄存器
1
,
[
源寄存器
2]
SWP
指令用于将源寄存器
2
所指向的存
储
器中的字数据
传
送到目的寄存器中,同
时
将源寄存器
1
中的字数据
传
送到源寄存器
2
所指向的存
储
器中。
显
然,当源寄存器
1
和目的寄存器
为
同一个寄存器
时
,指令交
换该
寄存器和存
储
器的内容。
指令示例:
SWP R0
,
R1
,
[R2]
;将
R2
所指向的存
储
器中的字数据
传
送到
R0
,同
时
将
R1
中的字数据
传
送到
R2
所指向的存
储单
元。
SWP R0
,
R0
,
[R1]
;
该
指令完成将
R1
所指向的存
储
器中的字数据与
R0
中的字数据交
换
。
2
、
SWPB
指令
SWPB
指令的格式
为
:
SWP{
条件
}B
目的寄存器,源寄存器
1
,
[
源寄存器
2]
SWPB
指令用于将源寄存器
2
所指向的存
储
器中的字
节
数据
传
送到目的寄存器中,目的寄存器的高
24
清零,同
时
将源寄存器
1
中的字
节
数据
传
送到源寄存器
2
所指向的存
储
器中。
显
然,当源寄存器
1
和目的寄存器
为
同一个寄存器
时
,指令交
换该
寄存器和存
储
器的内容。
指令示例:
SWPB R0
,
R1
,
[R2]
;将
R2
所指向的存
储
器中的字
节
数据
传
送到
R0
,
R0
的高
24
位清零,同
时
将
R1
中的低
8
位数据
传
送到
R2
所指向的存
储单
元。
SWPB R0
,
R0
,
[R1]
;
该
指令完成将
R1
所指向的存
储
器中的字
节
数据与
R0
中的低
8
位数据交
换
。
3.3.8 移位指令(操作)
3.3.8 移位指令(操作)
ARM
微
处
理器内嵌的桶型移位器(
Barrel Shifter
),支持数据的各
种
移位操作,移位操作在
ARM
指令集中不作
为单
独的指令使用,它只能作
为
指令格式中是一个字段,在
汇编语
言中表示
为
指令中的
选项
。例如,数据
处
理指令的第二个操作数
为
寄存器
时
,就可以加入移位操作
选项对
它
进
行各
种
移位操作。移位操作包括如下
6
种类
型,
ASL
和
LSL
是等价的,可以自由互
换
:
— LSL
逻辑
左移
— ASL
算
术
左移
— LSR
逻辑
右移
— ASR
算
术
右移
— ROR
循
环
右移
— RRX
带扩
展的循
环
右移
1
、
LSL
(或
ASL
)操作
LSL
(或
ASL
)操作的格式
为
:
通用寄存器,
LSL
(或
ASL
)
操作数
LSL
(或
ASL
)可完成
对
通用寄存器中的内容
进
行
逻辑
(或算
术
)的左移操作,按操作数所指定的数量向左移位,低位用零来填充。其中,操作数可以是通用寄存器,也可以是立即数(
0
~
31
)。
操作示例:
MOV R0, R1, LSL#2
;将
R1
中的内容左移两位后
传
送到
R0
中。
2
、
LSR
操作
LSR
操作的格式
为
:
通用寄存器,
LSR
操作数
LSR
可完成
对
通用寄存器中的内容
进
行右移的操作,按操作数所指定
的数量向右移位,左端用零来填充。其中,操作数可以是通用寄存器,也可以是立即数(
0
~
31
)。
操作示例:
MOV R0, R1, LSR#2
;将
R1
中的内容右移两位后
传
送到
R0
中,左端用零来填充。
3
、
ASR
操作
ASR
操作的格式
为
:
通用寄存器,
ASR
操作数
ASR
可完成
对
通用寄存器中的内容
进
行右移的操作,按操作数所指定的数量向右移位,左端用第
31
位的
值
来填充。其中,操作数可以是通用寄存器,也可以是立即数(
0
~
31
)。
操作示例:
MOV R0, R1, ASR#2
;将
R1
中的内容右移两位后
传
送到
R0
中,左端用第
31
位的
值
来填充。
4
、
ROR
操作
ROR
操作的格式
为
:
通用寄存器,
ROR
操作数
ROR
可完成
对
通用寄存器中的内容
进
行循
环
右移的操作,按操作数所指定的数量向右循
环
移位,左端用右端移出的位来填充。其中,操作数可以是通用寄存器,也可以是立即数(
0
~
31
)。
显
然,当
进
行
32
位的循
环
右移操作
时
,通用寄存器中的
值
不改
变
。
操作示例:
MOV R0, R1, ROR#2
;将
R1
中的内容循
环
右移两位后
传
送到
R0
中。
5
、
RRX
操作
RRX
操作的格式
为
:
通用寄存器,
RRX
操作数
RRX
可完成
对
通用寄存器中的内容
进
行
带扩
展的循
环
右移的操作,按操作数所指定的数量向右循
环
移位,左端用
进
位
标
志位
C
来填充。其中,操作数可以是通用寄存器,也可以是立即数(
0
~
31
)。
操作示例:
MOV R0, R1, RRX#2
;将
R1
中的内容
进
行
带扩
展的循
环
右移两位后
传
送到
R0
中。
3.3.9 协处 理器指令
ARM
微
处
理器可支持多达
16
个
协处
理器,用于各
种协处
理操作,在程序
执
行的
过
程中,
每
个
协处
理器只
执
行
针对
自身的
协处
理指令,忽略
ARM
处
理器和其他
协处
理器的指令。
ARM
的
协处
理器指令主要用于
ARM
处
理器初始化
ARM
协处
理器的数据
处
理操作,以及在
ARM
处
理器的寄存器和
协处
理器的寄存器之
间传
送数据,和在
ARM
协处
理器的寄存器和存
储
器之
间传
送数据。
ARM
协处
理器指令包括以下
5
条:
— CDP
协处
理器数操作指令
— LDC
协处
理器数据加
载
指令
— STC
协处
理器数据存
储
指令
— MCR ARM
处
理器寄存器到
协处
理器寄存器的数据
传
送指令
— MRC
协处
理器寄存器到
ARM
处
理器寄存器的数据
传
送指令
1
、
CDP
指令
CDP
指令的格式
为
:
CDP{
条件
}
协处
理器
编码
,
协处
理器操作
码
1
,目的寄存器,源寄存器
1
,源寄存器
2
,
协处
理器操作
码
2
。
CDP
指令用于
ARM
处
理器通知
ARM
协处
理器
执
行特定的操作
,
若
协处
理器不能成功完成特定的操作,
则产
生未定
义
指令异常。其中
协处
理器操作
码
1
和
协处
理器操作
码
2
为协处
理器将要
执
行的操作,目的寄存器和源寄存器均
为协处
理器的寄存器,指令不
涉
及
ARM
处
理器的寄存器和存
储
器。
指令示例:
CDP P3
,
2
,
C12
,
C10
,
C3
,
4
;
该
指令完成
协处
理器
P3
的初始化
2
、
LDC
指令
LDC
指令的格式
为
:
LDC{
条件
}{L}
协处
理器
编码
,
目的寄存器,
[
源寄存器
]
LDC
指令用于将源寄存器所指向的存
储
器中的字数据
传
送到目的寄存器中,若
协处
理器不能成功完成
传
送操作,
则产
生未定
义
指令异常。其中,
{L}
选项
表示指令
为长读
取操作,如用于双精度数据的
传输
。
指令示例:
LDC P3
,
C4
,
[R0]
;将
ARM
处
理器的寄存器
R0
所指向的存
储
器中的字数据
传
送到
协处
理器
P3
的寄存器
C4
中。
3
、
STC
指令
STC
指令的格式
为
:
STC{
条件
}{L}
协处
理器
编码
,
源寄存器,
[
目的寄存器
]
STC
指令用于将源寄存器中的字数据
传
送到目的寄存器所指向的存
储
器中,若
协处
理器不能成功完成
传
送操作,
则产
生未定
义
指令异常。其中,
{L}
选项
表示指令
为长读
取操作,如用于双精度数据的
传输
。
指令示例:
STC P3
,
C4
,
[R0]
;将
协处
理器
P3
的寄存器
C4
中的字数据
传
送到
ARM
处
理器的寄存器
R0
所指向的存
储
器中。
4
、
MCR
指令
MCR
指令的格式
为
:
MCR{
条件
}
协处
理器
编码
,
协处
理器操作
码
1
,源寄存器,目的寄存器
1
,目的寄存器
2
,
协处
理器操作
码
2
。
MCR
指令用于将
ARM
处
理器寄存器中的数据
传
送到
协处
理器寄存器中
,
若
协处
理器不能成功完
成操作,
则产
生未定
义
指令异常。其中
协处
理器操作
码
1
和
协处
理器操作
码
2
为协处
理器将要
执
行的操作,源寄存器
为
ARM
处
理器的寄存器,目的寄存器
1
和目的寄存器
2
均
为协处
理器的寄存器。
指令示例:
MCR P3
,
3
,
R0
,
C4
,
C5
,
6
;
该
指令将
ARM
处
理器寄存器
R0
中的数据
传
送到
协处
理器
P3
的寄存器
C4
和
C5
中。
5
、
MRC
指令
MRC
指令的格式
为
:
MRC{
条件
}
协处
理器
编码
,
协处
理器操作
码
1
,目的寄存器,源寄存器
1
,源寄存器
2
,
协处
理器操作
码
2
。
MRC
指令用于将
协处
理器寄存器中的数据
传
送到
ARM
处
理器寄存
器中
,
若
协处
理器不能成功完成操作,
则产
生未定
义
指令异常。其中
协处
理器操作
码
1
和
协处
理器操作
码
2
为协处
理器将要
执
行的操作,目的寄存器
为
ARM
处
理器的寄存器,源寄存器
1
和源寄存器
2
均
为协处
理器的寄存器。
指令示例:
MRC P3
,
3
,
R0
,
C4
,
C5
,
6
;
该
指令将
协处
理器
P3
的寄存器中的数据
传
送到
ARM
处
理器寄存器中。
3.3.10 异常 产 生指令
ARM
微
处
理器所支持的异常指令有如下两条:
— SWI
软
件中断指令
— BKPT
断点中断指令
1
、
SWI
指令
SWI
指令的格式
为
:
SWI{
条件
} 24
位的立即数
SWI
指令用于
产
生
软
件中断,以便用
户
程序能
调
用操作系
统
的系
统
例程。操作系
统
在
SWI
的异常
处
理程序中提供相
应
的系
统
服
务
,指令中
24
位的立即数指定用
户
程序
调
用系
统
例程的
类
型,相
关
参数通
过
通用寄存器
传递
,当指令中
24
位的立即数被忽略
时
,用
户
程序
调
用系
统
例程的
类
型由通用寄存器
R0
的内容决定,同
时
,参数通
过
其他通用寄存器
传递
。
指令示例:
SWI 0x02
;
该
指令
调
用操作系
统编
号位
02
的系
统
例程。
2
、
BKPT
指令
BKPT
指令的格式
为
:
BKPT 16
位的立即数
BKPT
指令
产
生
软
件断点中断,可用于程序的
调试
。
3.4 Thumb 指令及 应 用
3.4 Thumb 指令及 应 用
为
兼容数据
总线宽
度
为
16
位的
应
用系
统
,
ARM
体系
结
构除了支持
执
行效率很高的
32
位
ARM
指令集以外,同
时
支持
16
位的
Thumb
指令集。
Thumb
指令集是
ARM
指令集的一个子集,允
许
指令
编码为
16
位的
长
度。与等价的
32
位代
码
相比
较
,
Thumb
指令集在保留
32
代
码优势
的同
时
,大大的
节
省了系
统
的存
储
空
间
。
所有的
Thumb
指令都有
对应
的
ARM
指令,而且
Thumb
的
编
程模型也
对应
于
ARM
的
编
程模型,在
应
用程序的
编
写
过
程中,只要遵循一定
调
用的
规则
,
Thumb
子程序和
ARM
子程序就可以互相
调
用。当
处
理器在
执
行
ARM
程序段
时
,称
ARM
处
理器
处
于
ARM
工作状
态
,当
处
理器在
执
行
Thumb
程序段
时
,称
ARM
处
理器
处
于
Thumb
工作状
态
。
与
ARM
指令集相比
较
,
Thumb
指令集中的数据
处
理指令的操作数仍然是
32
位,指令地址也
为
32
位,但
Thumb
指令集
为实现
16
位的指令
长
度,舍弃了
ARM
指令集的一些特性,如大多数的
Thumb
指令是无条件
执
行的,而几乎所有的
ARM
指令都是有条件
执
行的;大多数的
Thumb
数据
处
理指令的目的寄存器与其中一个源寄存器相同。
由于
Thumb
指令的
长
度
为
16
位,即只用
ARM
指令一半的位数来
实现
同
样
的功能,所以,要
实现
特定的程序功能,所需的
Thumb
指令的条数
较
ARM
指令多。在一般的情况下,
Thumb
指令与
ARM
指令的
时间
效率和空
间
效率
关
系
为
:
— Thumb
代
码
所需的存
储
空
间约为
ARM
代
码
的
60
%~
70
%
— Thumb
代
码
使用的指令数比
ARM
代
码
多
约
30
%~
40
%
—
若使用
32
位的存
储
器,
ARM
代
码
比
Thumb
代
码
快
约
40
%
—
若使用
16
位的存
储
器,
Thumb
代
码
比
ARM
代
码
快
约
40
%~
50
%
—
与
ARM
代
码
相比
较
,使用
Thumb
代
码
,存
储
器的
功耗会降低
约
30
%
显
然,
ARM
指令集和
Thumb
指令集各有其
优
点,若
对
系
统
的性能有
较
高要求,
应
使用
32
位的存
储
系
统
和
ARM
指令集,若
对
系
统
的成本及功耗有
较
高要求,
则应
使用
16
位的存
储
系
统
和
Thumb
指令集。当然,若两者
结
合使用,充分
发挥
其各自的
优
点,会取得更好的效果。
3.5 本章小 节
本章系
统
的介
绍
了
ARM
指令集中的基本指令,以及各指令的
应
用
场
合及方法,由基本指令
还
可以派生出一些新的指令,但使用方法与基本指令
类
似。与常
见
的如
X86
体系
结
构的
汇编
指令相比
较
,
ARM
指令系
统
无
论
是从指令集本身,
还
是从
寻
址方
式上,都相
对复杂
一些。
Thumb
指令集作
为
ARM
指令集的一个子集,其使用方法与
ARM
指令集
类
似,在此未作
详细
的描述,但
这
并不意味着
Thumb
指令集不如
ARM
指令集重要,事
实
上,他
们
各自有其自己的
应
用
场
合
。