-
ARM
Thumb
指令集详解
ARM
Thumb
指令集详解
2010-04-27 12
:
30
来源:
MCU
p>
嵌入式领域
ARM Thumb
指令集
Thumb
指令可以看作是
ARM
指令压缩形式的子集,是针对代码密
度的问题
而提出的,它具有
16
位的代码密度。
Thumb
不是一个完整的体系结构,
不能指望处理只执行
p>
Thumb
指令而不支持
ARM
指令集。因此,
Thumb
指令只需要支
持通用功能,必要时可以借助于完善的
ARM
指
令集,比如,所有异常自动进入
ARM
状态。在编写
Thumb
指令时,先要使用伪指令
CODE16
声明,而且在
ARM
指令中要
使用
BX
指令跳转到
T
humb
指令,以切换处理器状态。编写
ARM
指令时,则可使用
伪指令
CODE32
声明。
1 Thumb
指令集与
ARM
指令集的区别
Thumb
指令
集没有协处
理器指令,信号量指令以及访问
CPSR
或
SPSR
的指令,没有乘加指令及
64
位乘法
指令等,且指令的第二操作数受到限制;
除了跳转指令
B
有条件执行功能外,其它
指令均为无条件执行;大多数
Thumb
数据处理指令采用<
/p>
2
地址格式。
Thumb
指令集
与
ARM
指令的区别一
般有如下几点:跳转指令程序相对转移,特别是条件跳转与
ARM
代码下的跳转相比,在范围上有更多的限制,转向子程序是无条件的转移。数
据处理指
令数据处理指令是对通用寄存器进行操作,在大多数情况下,操作的结果
须放入其中一个
操作数寄存器中,而不是第
3
个寄存器中。数据处理操作比
p>
ARM
状
态的更少,访问寄存器
R8~R15
受到一定限制。除
MOV
和
ADD
指令访问器
R8
~R15
外,其它数据处理指令总是更新
CPSR
中的
ALU
状态标志。访问寄存器
< br>R8~R15
的
Thumb
数据
处理指令不能更新
CPSR
中的
ALU
状态标志。单寄存器加载和存储指令
在
Thumb
状态下,单寄存器加载和存储指令只能访问寄存器
R
0~R7
。批量寄存器加
载和存储指令
LDM
和
STM
指令可以将任何范围为
R0~R7
的寄存器子集加载或存储。
PUSH
和
POP
指令使用堆栈指令<
/p>
R13
作为基址实现满递减堆栈。除
R0
~R7
外,
PUSH
指令还可以存储链
接寄存器
R14
,并且
POP
指令可以加载程序指令
PC
。
< br>2 Thumb
存
储器访问指令
Thumb
指令集的
LDM
和
SRM
指令可以将任何范围为
R0~R7
的寄存器子
集加载或存储。批量寄存器加载和存储指令只有
LDMIA
、
STMIA
指令,即每次传送
先加载
/
存储数据,
然后地址加
4
。对堆栈处理只能使用
P
USH
指令及
POP
指令。表
A-9
给出
Thumb
存储器访问指令。
表
A-9 Thu
mb
存储器访问指令
LDR
和
STR
立即数偏移的
LDR
和
STR
指令。存储器的
地址以一
个寄存器的立即数偏移指明。指令格式如下:
LDR
Rd,[
Rn,#immed_5×4];加载指定地址上的数据
(
p>
字
)
,放入
Rd<
/p>
中
STR
Rd,[Rn,#immed
_5×4];存储数据
(
字
)
到指定地址的存储单元,要存储数据在
Rd
中<
/p>
LDRH Rd,[Rn,#immed_5×4];加载半字数据,放入
Rd
中,即
Rd
低
16
位有效,高
16
位清零
STRH Rd,[Rn,
#immed_5×4];存储半字数据,要存储的数据在
Rd
,最低
16
位有效
LDRB Rd,[
Rn,#immed_5×4];加载字节数据,放入
Rd
中,
即
Rd
最低字
节有效,;高
24
位清零
STRB Rd,[Rn,#imme
d_5×4];存储字节数据,要存储的数
据在
Rd
,最低字节有效其中:
Rd
加载或存储的寄存器。必须为
R0~R7
。
< br>Rn
基址寄
存器。必须为
R0~
R7
。immed_5×N
偏移量。它是一个无符立即数表达式
,其取值为
(0~3)×N
立即数偏移的半字和字节加载是无符
号的。数据加载到
Rd
的最低有效半
字
或字节,
Rd
的其余位补
0
。地址对准一一字传送时,必须保证传送地址为
32
位
对准。半字传送时,必须保证传送地址为
16
位对准立即数偏移的
LDR
和
STR
指令
举例如下:
LDR
R0,[R1,#0x4]STR R3,[R4]LDRH R5,[R0,#0x02]STRH
R1,[R0,#0x08]LDRB R3,[R6,#20]STRB R1,[R
0,#31]
寄存器偏移的
LDR
和<
/p>
STR
指
令。存储器的地址用一个寄存器
的基于寄存器偏移来指明。指令格式如下:
LDR
Rd,[R
n,Rm]
;加载一个字数据
STR
Rd,[Rn,Rm]
;存储一个字数据
LDRH
Rd,[Rn,Rm]
;加载一个无符半字数据
S
TRH
Rd,[Rn,Rm]
;存储一个无符半字数据
LDRB
Rd,[Rn,Rm]
;加载一个无符字节数据
STRB Rd
,[Rn,Rm]
;存储一个无符字节
数据
LDRSH Rd,[Rn,Rm]
;加载一个有符半字数据
LDRSB R
d,[Rn,Rm]
;存储一个有
符半字数据其中:
Rd
加载或存储的寄存器。必须为
R0~R7
Rn
基址寄存器。必须为
R0~R7 Rm
内含偏移量的寄存器。必须为
R0~R7
。寄存器偏移的半
字和字节加载可以
是有符号或无符号的,数据加载到
Rd
的其余位拷贝符号位。地址对准
-
字传送时,
必须保证传送地址为
32
位对准。半字
传送时,必须保证传送地址为
16
位对准。寄
< br>存器偏移的
LDR
和
STR
p>
指令举例如下:
LDR R3,[R1,R0]STR
R1,[R0,R2]LDRH
R6,[R0,R1]STRH
R0,[R4,R5]LDRB R2,[R5,R1]STRB R1,[R3,R2]LDRSH
R7,[R6,R3]LDRSB R5,[R7,R2]PC
或
SP
相对偏移的
LDR
和
STR
指令。用
PC
p>
或
SP
寄
存器中的
值的立即数偏移来指明存储器的地址。指令格式如下:
LDR
Rd,[PC,#immed_8×4]LDR Rd,label LDR
Rd,[SP,#immed_8×4]STR
Rd,[SP,#immed_8×4
]其中:
Rd
加载或存储的寄存器。必须为
R0~R7
。immed_8×4]
偏移量。它是一个无符
立即数表达式,其取值为(0~255)×4。
label
程序
相对偏移
表达式。
label
必须在当
前指令之后
IK
字节范围内。地址对准
-
地址必须是
4
的整
< br>数倍。
PC
或
SP
相对偏移的
LDR
和
STR
指令举例如下:
LDR R0,[PC,#0x08]
;读取
PC+0x08
地址上的字数据,保存到
R0
中
LDR R7,LOCALDA
T
;读取
LOCALDAT
地址上
p>
的字数据,保存到
R7
中
< br>LDR R3,[SP,#1020]
;读取
SP+10
20
地址上的字数据,保
存到
R3
p>
中
STR R2,[SP]
;存储
R2
寄存器的数据到
SP
指向的存储单元
(
偏移量为
0)PU
SH
和
POP
寄存器入栈及出栈指令。
实现低寄存器和可选的
LR
寄存器入栈寄存
器和可选的
PC
寄存器出栈操作,堆栈地址由
SP
寄存设置,堆栈是满递减堆栈。指
令格式如下:
PUSH{reglist[,LR]}POP{reglist[,PC]}
其中:
reglist
入栈
/
出栈低
寄存器列表,即
R0~R
7
。
LR
入栈时的可选寄存器。
PC
出栈时的可选寄存器。寄存
器入栈及出栈
指令举例如下:
PUSH{R0-R7,LR}
;将低寄存器<
/p>
R0~R7
全部入栈,
LR
也入栈
POP{R0-R7,PC}
;将堆栈中的数
据弹出到低寄存器
R0~R7
及
PC<
/p>
中
LDMIA
和
STMIA
批量加载
/
存储指令可以实
现在一组寄存器和一块连续的内存单元之间传输
数据。
Thum
b
指令集批量加载
/
存储指令为
LDMIA
和
STMIA
,
LDMIA
为加载多个寄存
器;
STM
为存储多个寄存器,允许一条指令传送
< br>8
个低寄存器的任何子集。指令格
式如下:
LDMIA Rn
!
,reglist STMIA
Rn
!
,reglist
其中:
Rn
加载
/
存储的起
始地
址寄存器。
< br>Rn
必须为
R0~R7
。
Reglist
加载
/
存储的寄存器列表。寄存器必须为
R0~R7
。
LDMIA/STMIA
的主要用途是数据复制,参数传送等,进行数据传送
时,每
次传送后地址加
4
。若
Rn
在寄存器列表中,对于
LDMIA
指令,
Rn
的最终值是加载
的值,而不是增加后的地址;对于
STMIA
指令,在
p>
Rn
是寄存器列表中的最低数字
的寄存器,
则
Rn
存储的值为
Rn
在初值,其它情况不可预知。批量加载
/
存储指令
p>
举例如下:
LDMIA R0,{R2-R7}
;加载
R0
指向的地址上的多字数据,保存到
R2~R7
中,;
R0
的值
更新。
STMIA R1
!
,{R2-
R7}
;将
R2~R7
的数据存储到<
/p>
R1
指向的地址
上,
R1
值更新。
3 Thumb
数据
处理指令大多数
Thumb
处理指令采用
2
地址格式,数
据处理操作比
ARM
状态的更少,访问寄存器
R8~R15
受到一定限制。表
A-10
给出
Thu
mb
数据处理指令。
表
A-10 Thumb
数据处理指令
(1)
数据传送指令
MOV
数据传送指令。将
8
位立即数或
< br>寄存器
(operand2)
传送到目标寄存器
(Rd)
。指令格式如下:
MOV
Rd,#expr MOV
Rd,Rm
其中:
Rd
目标寄存器。
MOV Rd#expr
时,必须在
R0~R7
之间。
exper 8
位立
即数,即
0~
255
。
Rm
源寄存器,为
R0~R15
。条件码标志:
MOV Rd,#e
xpr
指令会更
新
N
< br>和
Z
标志,对标志
C
和
V
无影响。而
MOV,
Rd,Rm
指令,若
Rd
或
Rm
是高寄存器
(R8~R15)
,则标志不受影响,若
Rd
或
Rm
都是低寄存器
(R0~R7)
,则
会更新
N
和
Z
,且清除标志
C
和
V
< br>。
MOV
指令举例如下:
MOV
R1,#0x10
;
R1=0x10 MOV
R0,R8
;
R0=R8 MOV PC,LR
;
PC=LR
,子程序返回
M
VN
数据非传送指令。将寄存器
Rm
按
位取
反后传送到目标寄存器
(Rd)
。
指令格式如下:
MVN Rd,Rm
其中:
Rd
目标寄存器。必
须在
R0~R
7
之间。
Rm
源寄存器。必须在
R0~R7
之间。条件码标志:指令会更新
N
和
Z
标志,对标志
C
和
V
无影响。
< br>MVN
指令举例如下:
MVN R1,R2
;将
R2
取反结果
存到
p>
R1 NEG
数据取负指令。将寄存器
Rm
乘以
-1
后传送到目标寄存器
(Rd)
。指令
格式如下:
NEG Rd,Rm
其中:
Rd
目
标寄存器,必须在
R0~R7
之间。
R
m
源寄存器。
必须在
R0~R7
之间。条件码标志:指令会更新
N
、
Z
、
C
、
V
和标志。
NEG
指令举例
如下:
NEG R1,R0
;
R1=-R0(2)
算术逻辑运算指令
ADD<
/p>
加法运算指令。将两个数据相
加,结果保存到
Rd
寄存器。低寄存器的
ADD
指
令的指令格式如下:
ADD Rd,Rn,Rm
ADD
Rd,Rn,#expr3 ADD Rd,#expr8
其中:
Rd
目标寄存器,必须在
R0~R7
之间。
Rn
第一个操作数寄存器。必须在
R0~R7
之间。
Rm
第二个操作数
寄存器。必须在
R0~R7
之间。
ex
pr3 3
位立即数,即
0~7
。
p>
expr8 8
位立即数,即
0~255<
/p>
。条件码标志:指
令会更新
N
、
Z
、
C
和
V
标志。高或低寄存器的
A
DD
指令的指令格式如下:
ADD
R
d,Rm
其中:
Rd
目标寄存器,也是
第一个操数寄存器。
Rm
第二个操作数寄存器条
件码标志:若
Rd
或
Rm
p>
都是低寄存器
(R0~R7)
,指令会更新
N
、
Z
、
p>
C
和
V
标志。其<
/p>
它情况不影响条件码标志。
PC
或
SP
相对偏移的
ADD
指令指令格式如下:
ADD
Rd,Rp,#expr
其中:
Rd
目标寄存器,必须在
R0~R7
之间。
Rp PC
或
SP
,第一个操作
数寄存器。
p>
expr
立即数,在
0~1020
范围内。条件码标志:不影响条件码标志。
SP
操作的
ADD
指令的指令格式如下:
A
DD SP,#expr ADD SP,SP,#expr
其中:
SP
目标
寄存器,也是第一个操作数寄存器。
expr
立即数,在
-508~+508
之间的
4
的整数倍
的数。
条件码标志:不影响条件码标志。
ADD
指令举例如下:
ADD
R1,R1,R0
;
R1=R1+R0 ADD
R1,R1,#7
;
R1=R1+7 ADD
R3,#200
;
R3=R3+200 ADD
R3,R8
;
R3=R3+R8 ADD
R1,SP,#1000
;
R1=SP+1000 ADD
SP,SP,#-500
;
SP=SP-500
SUB
减法