第二章ARM/Thumb
微处理器结构及指令系
统
ARM/THUMB指令系统
1. ARM处理器寻址方式
2. ARM指令集介绍
3. Thumb指令集
处理器寻址方式
寻址方式是根据指令中给出的地址码字段来实现
寻找真实操作数地址的方式。ARM处理器具有9种
基本寻址方式。
(1).寄存器寻址; (2).立即寻址;
(3).寄存器偏移寻址; (4).寄存器间接寻址;
(5).基址寻址; (6).多寄存器寻址;
(7).堆栈寻址; (8).块拷贝寻址;
(9).相对寻址。
操作数的值在寄存器中,指令中的地址码字段指出的
是寄存器编号,指令执行时直接取出寄存器值来操作。
寄存器寻址指令举例如下:
MOV R1,R2 ;将R2的值存入R1
SUB R0,R1,R2 ;将R1的值减去R2的值,结果保存到R0
0xAA
0x55
R2
R1
(1).寄存器寻址
MOV R1,R2
0xAA
立即寻址指令中的操作码字段后面的地址码部分即是
操作数本身,也就是说,数据就包含在指令当中,取出指
令也就取出了可以立即使用的操作数(这样的数称为立即数)。
立即寻址指令举例如下:
SUBS R0,R0,#1 ;R0减1,结果放入R0,并且影响标志
位
MOV R0,#0xFF000 ;将立即数0xFF000装入R0寄存器
0x55R0
MOV R0,#0xFF00
程序存储
(2).立即寻址
MOV R0,#0xFF00
0xFF00
从代码中获得数据
寄存器移位寻址是ARM指令集特有的寻址方式。当第2
个操作数是寄存器移位方式时,第2个寄存器操作数在与第1
个操作数结合之前,选择进行移位操作。寄存器移位寻址指
令举例如下:
MOV R0,R2,LSL #3 ;R2的值左移3位,结果放入R0,
;即是R0=R2×8
ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后和R1相
;“与”操作,结果放入R1
0x55R0
R2 0x01
(3).寄存器偏移寻址
MOV R0,R2,LSL #3
0x08
0x08
逻辑左移3位
寄存器间接寻址指令中的地址码给出的是一个通用寄
存器的编号,所需的操作数保存在寄存器指定地址的存
储单元中,即寄存器为操作数的地址指针。寄存器间接
寻址指令举例如下:
LDR R1,[R2] ;将R2指向的存储单元的数据读出
;保存在R1中
SWP R1,R1,[R2] ;将寄存器R1的值和R2指定的存储
;单元的内容交换
0x55R0
R2 0x40000000
0xAA0x40000000
(4).寄存器间接寻址
LDR R0,[R2]
0xAA
基址寻址就是将基址寄存器的内容与指令中给出的偏移
量相加,形成操作数的有效地址。基址寻址指令举例如下:
LDR R2,[R3,#0x0C] ;读取R3+0x0C地址上的存储单元
;的内容,放入R2
STR R1,[R0,#-4]! ;先R0=R0-4,然后把R1的值寄存
;到保存到R0指定的存储单元
(5).基址寻址
0x55R2
R3 0x40000000
0xAA0x4000000C
LDR R2,[R3,#0x0C]
0xAA
将R3+0x0C作
为地址装载数
据
多寄存器寻址一次可传送几个寄存器值,允许一条指令传送16个寄
存器的任何子集或所有寄存器。
多寄存器寻址指令举例如下:
LDMIA R1!,{R2-R7,R12} ;将R1指向的单元中的数据读出到
;R2~R7、R12中(R1自动加1)
STMIA R0!,{R2-R7,R12} ;将寄存器R2~R7、R12的值保
;存到R0指向的存储; 单元中
;(R0自动加1)
使用多寄存器寻址指令时,寄
存器子集的顺序是按由小到大的顺
序排列,连续的寄存器可用“-”
连接;否则用“,”分隔书写。
(6).多寄存器寻址
0x40000000R1
R2 0x?? 0x01 0x40000000
0x??R3
R4 0x??
R6 0x??
0x02
0x03
0x04
0x40000004
0x40000008
0x4000000C
存储器
LDMIA R1!,{R2-R4,R6}
0x40000010
0x01
0x02
0x03
0x04
堆栈是一个按特定顺序进行存取的存储区,操作顺序为
“后进先出” 。堆栈寻址是隐含的,它使用一个专门的寄
存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存
储单元即是堆栈的栈顶。存储器堆栈可分为两种:
向上生长:向高地址方向生长,称为递增堆栈
向下生长:向低地址方向生长,称为递减堆栈
(7).堆栈寻址
(7).堆栈寻址
栈底
栈顶
栈区
SP
堆栈存
储区
栈顶
栈底
栈区
SP
向下
增长
向上
增长
0x12345678
0x12345678堆栈压栈
堆栈压栈
栈顶SP
栈顶SP
栈底
空堆栈
栈底
满堆栈
堆栈指针指向最后压入的堆栈的有效数据项,称
为满堆栈;堆栈指针指向下一个待压入数据的空位
置,称为空堆栈。
(7).堆栈寻址
0x12345678
0x12345678栈顶SP 0x12345678
栈顶SP
压栈 压栈
所以可以组合出四种类型的堆栈方式:
满递增:堆栈向上增长,堆栈指针指向内含有效数据项
的最高地址。指令如LDMFA、STMFA等;
空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个
空位置。指令如LDMEA、STMEA等;
满递减:堆栈向下增长,堆栈指针指向内含有效数据项
的最低地址。指令如LDMFD、STMFD等;
空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空
位置。指令如LDMED、STMED等。
(7).堆栈寻址
多寄存器传送指令用于将一块数据从存储器的某一位置拷贝到另
一位置。 如:
STMIA R0!,{R1-R7} ;将R1~R7的数据保存到存储器中。
;存储指针在保存第一个值之后增加,
;增长方向为向上增长。
STMIB R0!,{R1-R7} ;将R1~R7的数据保存到存储器中。
;存储指针在保存第一个值之前增加,
;增长方向为向上增长。
(8).块拷贝寻址
增加
之前 STMIB
STMFA
LDMIB
LDMED
之后 STMIA
STMEA
LDMIA
LDMFD
减少
之前 LDMDB
LDMEA
STMDB
STMFD
之后 LDMDA
LDMFA
STMDA
STMED
向上生长 向下生长
满 空 满 空
增长的方向
增长的先后
多寄存器传送指令映射
相对寻址是基址寻址的一种变通。由程序计数
器PC提供基准地址,指令中的地址码字段作为偏移
量,两者相加后得到的地址即为操作数的有效地址。
相对寻址指令举例如下:
BL SUBRl ;调用到SUBRl子程序
. . .
SUBR1…
MOV PC,R14 ;返回
(7). 相对寻址
2. ARM指令集介绍
(1).指令格式
(2).条件码
(3).ARM存储器访问指令
(4). ARM数据处理指令
(5).乘法指令
(6). ARM分支指令
(7).协处理器指令
(8).杂项指令
(9).伪指令
2. ARM指令集介绍
ARM7TDMI(-S)的指令集,包括
ARM指令集
Thumb指令集。
首先介绍ARM指令的基本格式及灵活的操作数,然后
介绍条件码,再把ARM指令集、Thumb指令集按类分别说明。
ARM指令的基本格式如下:
(1).指令格式
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}
其中<>号内的项是必须的,{}号内的项是可选的。
各项的说明如下:
opcode:指令助记符; cond:执行条件;
S:是否影响CPSR寄存器的值;
Rd:目标寄存器; Rn:第1个操作数的寄存器;
operand2:第2个操作数;
LDR R0,[R1] ;读取R1地址上的存储器单元内容,执行条件AL
BEQ D1 ;分支指令,执行条件EQ,即相等则跳转到D1
ADDS R1,R1,#1 ;加法指令,R1+1=>R1,影响CPSR
;寄存器(S)
SUBNES R1,R1,#0x10 ;条件执行减法运算(NE),R1 -
; 0x10=>R1,影响CPSR寄存器(S)
指令格式举例如下:
(1).指令格式:
灵活的使用第2个操作数“operand2”能够提高代
码效率。它有如下的形式:
#immed_8r——常数表达式;
Rm——寄存器方式;
Rm,shift——寄存器移位方式;
第2个操作数
(1).指令格式:第2个操作数
#immed_8r——常数表达式
该常数必须对应8位位图,即一个8位的常数通过
循环右移偶数位得到。
循环右移10位
0x12
0 0 0 1 0 0 1 0
0x00
0 0 0 0 0 0 0 0
0x00
0 0 0 0 0 0 0 0
0x00
0 0 0 0 0 0 0 0
0x00
0 0 0 0 0 0 0 0
0x00
0 0 0 0 0 0 0 0
0x80
1 0 0 0 0 0 0 0
0x04
0 0 0 0 0 1 0 0
8位常数
(1).指令格式:第2个操作数
合 法 常 量 : 0x3FC、 0、 0xF0000000、 200、
0xF0000001。
非法常量 : 0xlFE、511、0xFFFF、0x1010、
0xF0000010。
#immed_8r——常数表达式
常数表达式应用举例:
MOV R0,#1 ;R0=1
AND R1,R2,#0x0F ;R2与0x0F,结果保存在Rl
LDR R0,[R1],#-4 ;读取R1地址上的存储器单元内容,且 R1
= R1- 4
(1).指令格式:第2个操作数
Rm——寄存器方式
在寄存器方式下,操作数即为寄存器的数值。寄存器方式应用
举例:
SUB R1,R1,R2 ;R1-R2→R1
MOV PC,R0 ;PC=R0,程序跳转到指定地址
LDR R0,[R1],-R2 ;Rl所指存储器单元
内容存人R0,且R1 = R1 - R2
(1).指令格式:第2个操作数
Rm,shift——寄存器移位方式
将寄存器的移位结果作为操作数,但Rm值保持不变,
移位方法如下:
操作码 说明 操作码 说明
ASR #n 算术右移n位 ROR #n 循环右移n位
LSL #n 逻辑左移n位 RRX 带扩展的循环右移1位
LSR #n 逻辑右移n位 Type Rs
Type为移位的一种类型,Rs
为偏移量寄存器,低8位有效。
(1).指令格式:第2个操作数
LSL移位操作: 0
LSR移位操作: 0
ASR移位操作:
ROR移位操作:
RRX移位操作: C
寄存器偏移方式应用举例:
ADD R1ADD R1,,R1R1,,R1R1,,LSL #3 LSL #3 ;;R1=R1×9R1=R1×9
SUB R1SUB R1,,R1R1,,R2R2,,LSR #2 LSR #2 ;;R1=R1-R2×4R1=R1-R2×4
ARM指令的基本格式如下:
(2).条件码
<opcode> {<cond>} {S} <Rd> ,<Rn>{,<operand2>}
使用条件码“cond”可以实现高效的逻辑操作,提
高代码效率。
所有的ARM指令都可以条件执行,而Thumb指令
只有B(跳转)指令具有条件执行 功能。如果指令不标
明条件代码,将默认为无条件(AL)执行。
操作码 条件助记符 标志 含义
0000 EQ Z=1 相等
0001 NE Z=0 不相等
0010 CS/HS C=1 无符号数大于或等于
0011 CC/LO C=0 无符号数小于
0100 MI N=1 负数
0101 PL N=0 正数或零
0110 VS V=1 溢出
0111 VC V=0 没有溢出
1000 HI C=1,Z=0 无符号数大于
1001 LS C=0,Z=1 无符号数小于或等于
1010 GE N=V 有符号数大于或等于
1011 LT N!=V 有符号数小于
1100 GT Z=0,N=V 有符号数大于
1101 LE Z=1,N!=V 有符号数小于或等于
1110 AL 任何 无条件执行 (指令默认条件)
1111 NV 任何 从不执行(不要使用)
• 指令条件码表
(3). ARM存储器访问指令
ARM处理器是典型的RISC处理器,对存储器
的访问只能使用加载和存储指令实现。ARM处理器
是冯•诺依曼存储结构,程序空间、RAM空间及I/O
映射空间统一编址,除对RAM操作以外,对外围IO、
程序数据的访问均要通过加载/存储指令进行。
存储器访问指令分为单寄存器操作指令和多寄
存器操作指令。
助记符 说明 操作 条件码位置
LDR Rd,addressing 加载字数据
Rd←[addressing],
addressing索引
LDR{cond}
LDRB Rd,addressing 加载无符号字节数据
Rd←[addressing],
addressing索引
LDR{cond}B
LDRT Rd,addressing 以用户模式加载字数
据
Rd←[addressing],
addressing索引
LDR{cond}T
LDRBT Rd, addressing 以用户模式加载无符
号字节数据
Rd←[addressing],
addressing索引
LDR{cond}BT
LDRH Rd, addressing 加载无符号半字数据
Rd←[addressing],
addressing索引
LDR{cond}H
LDRSB Rd, addressing 加载有符号字节数据
Rd←[addressing],
addressing索引
LDR{cond}SB
LDRSH Rd, addressing 加载有符号半字数据
Rd←[addressing],
addressing索引
LDR{cond}SH
(3). ARM存储器访问指令:单寄存器加载
助记符 说明 操作 条件码位置
STR Rd, addressing 存储字数据 [addressing]←Rd,
addressing索引
STR{cond}
STRB Rd,addressing 存储字节数据 [addressing]←Rd,
addressing索引
STR{cond}B
STRT Rd,addressing 以用户模式存储字数
据
[addressing]←Rd,
addressing索引
STR{cond}T
STRBT Rd,addressing 以用户模式存储字节
数据
[addressing]←Rd,
addressing索引
STR{cond}BT
STRH Rd,addressing 存储半字数据 [addressing] ←Rd,
addressing索引
STR{cond}H
(3). ARM存储器访问指令:单寄存器存储
LDR/STR指令用于对内存变量的访问、内存缓冲区数据的访问、查表、
外围部件的控制操作等。若使用LDR指令加载数据到PC寄存器,则实现程
序跳转功能,这样也就实现了程序散转。
说明:
所有单寄存器加载/存储指令可分为
“字和无符号字节加载存储指令”
“半字和有符号字节加载存储指令。
•LDR和STR——字和无符号字节加载/存储指令
LDR指令用于从内存中读取单一字或字节数据
存入寄存器中,STR指令用于将寄存器中的单一字
或字节数据保存到内存。指令格式如下:
(3). ARM存储器访问指令:单寄存器存储
LDR{cond}{T} Rd,<地址> ;将指定地址上的字数据读入Rd
STR{cond}{T} Rd,<地址> ;将Rd中的字数据存入指定地址
LDR{cond}B{T} Rd,<地址> ;将指定地址上的字节数据读入Rd
STR{cond}B{T} Rd,<地址> ;将Rd中的字节数据存入指定地址
注意:T为可选后缀。若指令
有T,那么即使处理器是在特
权模式下,存储系统也将访问
看成是在用户模式下进行的。
T在用户模式下无效,不能与
前索引偏移一起使用T。
(3). ARM存储器访问指令:单寄存器存储
•LDR和STR——字和无符号字节加载/存储指令编码
指令执行的条件码
I为0时,偏移量为12
位立即数,为1时,
偏 移 量 为 寄 存 器 移
位
P表示前/后变址
U表示加/减
B为1表示字节访问,
为0表示字访问
W表示回写
为指令的寻址方式
Rd为源/目标寄存器
Rn为基址寄存器
L用于区别加载(L为1)
或存储(L为0)
(3). ARM存储器访问指令:单寄存器存储
•LDR和STR——字和无符号字节加载/存储指令
LDR/STR指令寻址非常灵活,它由两部分组成,其中一
部分为一个基址寄存器,可以为任一个通用寄存器;另一部
分为一个地址偏移量。地址偏移量有以下3种格式:
立即数:立即数可以是一个无符号的数值。这个数据可以加
到基址寄存器,也可以从基址寄存器中减去这个数值。
寄存器:寄存器中的数值可以加到基址寄存器,也可以从基
址寄存器中减去这个数值。
寄存器及移位常数:寄存器移位后的值可以加到基址寄存器,
也可以从基址寄存器中减去这个数值。
指令举例如下:指令举例如下:
LDR R1LDR R1,,[R0[R0,,#0x12] #0x12] ;将;将R0+0x12R0+0x12地地
址处的数据读出,保存到址处的数据读出,保存到RlRl中中(R0(R0的值不变的值不变))
LDR R1LDR R1,,[R0[R0,,# -0x12] # -0x12] ;将;将R0-0x12R0-0x12地地
址处的数据读出,保存到址处的数据读出,保存到R1R1中中(R0(R0的值不变的值不变) )
指令举例如下:指令举例如下:
LDR R1LDR R1,,[R0[R0,,R2] R2] ;将;将R0+R2R0+R2地址处的数地址处的数
据读出,保存到据读出,保存到R1R1中中
LDR R1LDR R1,,[R0[R0,,-R2] -R2] ;将;将R0-R2R0-R2地址处的数地址处的数
据读出,保存到据读出,保存到R1R1中中
指令举例如下:指令举例如下:
LDR R1LDR R1,,[R0[R0,,R2R2,,LSL #2]LSL #2] ;将;将
R0+R2×4R0+R2×4地址处的数据读出,保存到地址处的数据读出,保存到R1R1中中(R0(R0、、
R2R2的值不变的值不变))
LDR R1LDR R1,,[R0[R0,,-R2-R2,,LSL #2]LSL #2];将;将R0-R2×4R0-R2×4
地址处的数据读出,保存到地址处的数据读出,保存到R1R1中中(R0(R0、、R2R2的值的值
不变不变) )
(3). ARM存储器访问指令:单寄存器存储
从寻址方式的地址计算方法分,加载/存储指令有以下4
种格式:
零偏移: 如:LDR Rd,[Rn]
前索引偏移: 如:LDR Rd,[Rn,#0x04]!
LDR Rd,[Rn,# -0x04]
程序相对偏移: 如:LDR Rd,labe1
后索引偏移: 如:LDR Rd,[Rn],#0x04
•LDR和STR——字和无符号字节加载/存储指令
注意:
大多数情况下,必须
保证字数据操作的地址是
32位对齐的。
•LDR和STR——半字和有符号字节加载/存储指令
这类LDR/STR指令可加载有符号半字或字节,可加载/存
储无符号半字。偏移量格式、寻址方式与加载/存储字和无符
号字节指令相同。
注意:
1.有符号位半字/字节加载是指用符号位加载扩展到32位,无符号
半字加载是指用零扩展到32位;
2.地址对齐——半字读写的指定地址必须为偶数,否则将产生不可
靠的结果。
(3). ARM存储器访问指令:单寄存器存储
LDR{cond}SB Rd,<地址> ;将指定地址上的有符号字节读入Rd
LDR{cond}SH Rd,<地址> ;将指定地址上的有符号半字读入
Rd
LDR{cond}H Rd,<地址> ;将指定地址上的半字数据读入Rd
STR{cond}H Rd,<地址> ;将Rd中的半字数据存入指定地址
(3). ARM存储器访问指令:单寄存器存储
•LDR和STR——半字和有符号字节加载/存储指令编码
举例如下:
LDRSB R1,[R0,R3] ;将R0+R3地址上的字节数据读到R1,高24位
;用符号位扩展
LDRSH R1,[R9] ;将R9地址上的半字数据读出到R1,高16位用符号
; 位扩展
LDRH R6,[R2],#2;将R2地址上的半字数据读出到R6,高16位用零扩
; 展,R2=R2+2
STRH R1,[Ro,#2]! ;将R1的数据保存到R0+2地址中,只存储低2
;字节数据,R0=R0+2
说明:
LDR/STR指令用于对内存变量
的访问、内存缓冲区数据的访问、查
表、外围部件的控制操作等等。若使
用LDR指令加载数据到PC寄存器,
则实现程序跳转功能,这样也就实现
了程序散转。
(3). ARM存储器访问指令:
LDM和STM指令可以实现在一组寄存器和一块连续的内存单元之间传
输数据。
LDM为加载多个寄存器;
STM为存储多个寄存器。
允许一条指令传送16个寄存器的任何子集或所有寄存器。
指令格式如下:
LDM{cond}<模式> Rn{!},reglist{^}
STM{cond}<模式> Rn{!},reglist{^}
多寄存器存取
LDM和STM的主要用途是现场保护、数据复制、常数传递等
(3). ARM存储器访问指令:多寄存器存取
多寄存器加载/存储指令的8种模式如下表所示,右边四种为堆栈
操作、左边四种为数据传送操作。
模式 说明 模式 说明
IA 每次传送后地址加4 FD 满递减堆栈
IB 每次传送前地址加4 ED 空递减堆栈
DA 每次传送后地址减4 FA 满递增堆栈
DB 每次传送前地址减4 EA 空递增堆栈
数据块传送操作 堆栈操作
进行数据复制时,先设置好源数据指针和目标指针,然后使用块
拷 贝 寻 址 指 令 LDMIA/STMIA、 LDMIB/STMIB、 LDMDA/STMDA、
LDMDB/STMDB进行读取和存储 。
进行堆栈操作操作时,要先设置堆栈指针(SP),然后使用堆栈
寻 址 指 令 STMFD/LDMFD 、 STMED/LDMED、 STMFA/LDMFA和
STMEA/LDMEA实现堆栈操作。
指令格式中,寄存器Rn为基址寄存器,装有传
送数据的初始地址,Rn不允许为R15。
后缀“!”表示最后的地址写回到Rn中。
寄存器列表reglist可包含多于一个寄存器或包含寄存
器范围,使用“,”分开,如{R1,R2,R6~R9},寄
存器按由小到大排列。
后缀“^”不允许在用户模式或系统模式下使用。
若在LDM指令且寄存器列表中包含有PC时使用,那么
除了正常的多寄存器传送外,将SPSR也拷贝到CPSR中,
这可用于异常处理返回。
使用后缀“^”进行数据传送且寄存器列表不包
含PC时,加载/存储的是用户模式的寄存器,而不是
当前模式的寄存器。
当Rn在寄存器列表中且使用后缀“!”时,对于
STM指令,若Rn为寄存器列表中的最低数字的寄存器,则
会将Rn的初值保存;其它情况下Rn的加载值和存储值不
可预知。
地址对齐—这些指令忽略地址位[1:0]。
举例如下:
LDMIA R0!,{R3 - R9};加载R0指向地址上的多字数据,保存
;到R3~R9中,R0值更新
STMIA R1!,{R3 - R9};将R3~R9的数据存储到R1指向的地址
;上,R1值更新
STMFD SP!,{R0 - R7,LR} ;现场保存,将R0~R7、LR人栈
LDMFD SP!,{R0 - R7,PC} ;恢复现场,异常处理返回
(3). ARM存储器访问指令:
SWP指令用于将一个内存单元(该单元地址放在寄存器Rn中)的
内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入
到该内存单元中。使用SWP可实现信号量操作。
指令格式如下:
SWP{cond}{B} Rd,Rm,[Rn]
其中,B为可选后缀,若有B,则交换字节,否则交换32位字;
Rd用于保存从存储器中读入的数据;Rm的数据用于存储到存储器
中,若Rm与Rn相同,则为寄存器与存储器内容进行交换;Rn为要
进行数据交换的存储器地址,Rn不能与Rd和Rm相同。
SWP指令应用示例:
SWP R1,R1,[R0] ;将R1的内容与R0指向的存储单元的内容进行交换
SWPB R1,R2,[R0] ;将R0指向的存储单元内的容读取一字节数据到R1中
;(高24位清零),并将R2的内容写入到该内存单元中
;(最低字节有效)
寄存器和存储器交换指令
(4).ARM数据处理指令
数据处理指令大致可分为3类:
数据传送指令;
算术逻辑运算指令;
比较指令。
数据处理指令只能对寄存器的内容进行操作,
而不能对内存中的数据进行操作。所有ARM数据处
理指令均可选择使用S后缀,并影响状态标志。
比较指令CMP、CMN、TST和TEQ不需要后
缀S,它们会直接影响状态标志。
助记符 说明 操作 条件码位置
MOV Rd,operand2 数据传送 Rd←operand2 MOV{cond}{S}
MVN Rd,operand2 数据非传送 Rd←(~operand2) MVN{cond}{S}
(4). ARM数据处理指令:数据传送
助记符 说明 操作 条件码位置
MOV Rd,operand2 数据传送 Rd←operand2 MOV{cond}{S}
MVN Rd,operand2 数据非传送 Rd←(~operand2) MVN{cond}{S}
MOV指令将8位图立即数(参看“第2操作数:#immed_8r——常数表
达式”)或寄存器传送到目标寄存器(Rd),可用于移位运算等操作。指
令格式如下:
MOV{cond}{S} Rd,operand2
(4). ARM数据处理指令:数据传送
MOV指令举例如下:
MOVSR3,R1,LSL #2 ;R3=R1<<2,并影响标志位
MOV PC,LR ;PC=LR,子程序返回
助记符 说明 操作 条件码位置
MOV Rd,operand2 数据传送 Rd←operand2 MOV{cond}{S}
MVN Rd,operand2 数据非传送 Rd←(~operand2) MVN{cond}{S}
MVN指令将8位图立即数(参看“第2操作数:#immed_8r——常数表
达式”)或寄存器(operand2)按位取反后传送到目标寄存器(Rd),因
为其具有取反功能,所以可以装载范围更广的立即数。指令格式如下:
MVN{cond}{S} Rd,operand2
(4). ARM数据处理指令:数据传送
MVN指令举例如下:
MVN R1,#0xFF ;R1=0xFFFFFF00
MVN R1,R2 ;将R2取反,结果存到R1
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
SBC Rd, Rn, operand2 带进位减法指令
Rd←Rn-operand2-
(NOT)Carry
SBC{cond}{S}
RSC Rd, Rn, operand2
带进位逆向减法
指令
Rd←operand2-Rn-
(NOT)Carry
RSC{cond}{S}
(4). ARM数据处理指令:算术运算
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
SBC Rd, Rn, operand2 带进位减法指令
Rd←Rn-operand2-
(NOT)Carry
SBC{cond}{S}
RSC Rd, Rn, operand2
带进位逆向减法
指令
Rd←operand2-Rn-
(NOT)Carry
RSC{cond}{S}
加法运算指令——ADD指令将operand2的值与Rn的值相
加,结果保存到Rd寄存器。指令格式如下:
ADD{cond}{S} Rd,Rn,operand2
(4). ARM数据处理指令:算术运算
应用示例:
ADDS R1,R1,#1 ;R1=R1+1,并影响标志位
ADDS R3,R1,R2,LSL #2 ; R3=R1+R2<<2
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
SBC Rd, Rn, operand2 带进位减法指令
Rd←Rn-operand2-
(NOT)Carry
SBC{cond}{S}
RSC Rd, Rn, operand2
带进位逆向减法
指令
Rd←operand2-Rn-
(NOT)Carry
RSC{cond}{S}
减法运算指令——SUB指令用寄存器Rn减去operand2,结
果保存到Rd中。指令格式如下:
SUB{cond}{S} Rd,Rn,operand2
(4). ARM数据处理指令:算术运算
应用示例:
SUBS R0,R0,#1 ;R0=R0-1
SUB R6,R7,#0x10 ; R6=R7-0x10
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
SBC Rd, Rn, operand2 带进位减法指令
Rd←Rn-operand2-
(NOT)Carry
SBC{cond}{S}
RSC Rd, Rn, operand2
带进位逆向减法
指令
Rd←operand2-Rn-
(NOT)Carry
RSC{cond}{S}
逆向减法运算指令——RSB指令将operand2的值减去Rn,
结果保存到Rd中。指令格式如下:
RSB{cond}{S} Rd,Rn,operand2
(4). ARM数据处理指令:算术运算
应用示例:
RSB R3,R1,#0xFF00 ;R3=0xFF00-R1
RSBS R1,R2,R2,LSL #2 ;R1=(R2<<2)-R2=R2×3
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
SBC Rd, Rn, operand2 带进位减法指令
Rd←Rn-operand2-
(NOT)Carry
SBC{cond}{S}
RSC Rd, Rn, operand2
带进位逆向减法
指令
Rd←operand2-Rn-
(NOT)Carry
RSC{cond}{S}
带进位加法指令——ADC将operand2的值与Rn的值相加,
再加上CPSR中的C条件标志位,结果保存到Rd寄存器。指令格
式如下:
ADC{cond}{S} Rd,Rn,operand2
(4). ARM数据处理指令:算术运算
应用示例:
ADDS R0,R0,R2 ;使用ADC实现64位加法
ADC R1,R1,R3 ;(R1、R0)=(R1、R0)+(R3、
R2)
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
SBC Rd, Rn, operand2 带进位减法指令
Rd←Rn-operand2-
(NOT)Carry
SBC{cond}{S}
RSC Rd, Rn, operand2
带进位逆向减法
指令
Rd←operand2-Rn-
(NOT)Carry
RSC{cond}{S}
带进位减法指令——SBC用寄存器Rn减去operand2,再减
去CPSR中的C条件标志位的非(即若C标志清零,则结果减去1)
,结果保存到Rd中。指令格式如下:
SBC{cond}{S} Rd,Rn,operand2
(4). ARM数据处理指令:算术运算
应用示例:
SUBS R0,R0,R2 ;使用SBC实现64位减法
SBC R1,R1,R3; (R1、R0)=(R1、R0)-(R3、R2)
助记符 说明 操作 条件码位置
ADD Rd, Rn, operand2 加法运算指令 Rd←Rn+operand2 ADD{cond}{S}
SUB Rd, Rn, operand2 减法运算指令 Rd←Rn-operand2 SUB{cond}{S}
RSB Rd, Rn, operand2 逆向减法指令 Rd←operand2-Rn RSB{cond}{S}
ADC Rd, Rn, operand2 带进位加法 Rd←Rn+operand2+Carry ADC{cond}{S}
SBC Rd, Rn, operand2 带进位减法指令
Rd←Rn-operand2-
(NOT)Carry
SBC{cond}{S}
RSC Rd, Rn, operand2
带进位逆向减法
指令
Rd←operand2-Rn-
(NOT)Carry
RSC{cond}{S}
带进位逆向减法指令——RSC指令用寄存器operand2减去
Rn,再减去CPSR中的C条件标志位,结果保存到Rd中。指令
格式如下:
RSC{cond}{S} Rd,Rn,operand2
(4). ARM数据处理指令:算术运算
应用示例:
RSBS R2,R0,#0
RSC R3,R1,#0 ;使用RSC指令实现求64位数值的负数
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}
(4). ARM数据处理指令: 逻辑运算指令
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}
逻辑与操作指令——AND指令将operand2的值与寄存器
Rn的值按位作逻辑“与”操作,结果保存到Rd中。指令格式
如下:
AND{cond}{S} Rd,Rn,operand2
(4). ARM数据处理指令:逻辑运算指令
应用示例:
ANDS R0,R0,#0x01 ;R0=R0&0x01,取出最低位数据
AND R2,R1,R3 ;R2=R1&R3
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}
逻辑或操作指令——ORR指令将operand2的值与寄存器Rn的值按位作
逻辑“或”操作,结果保存到Rd中。指令格式如下:
ORR{cond}{S} Rd,Rn, operand2
应用示例:
ORR R0,R0,#0x0F ;将R0的低4位置1
(4). ARM数据处理指令:逻辑运算指令
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}
逻辑异或操作指令——EOR指令将operand2的值与寄存器Rn的值按位
作逻辑“异或”操作,结果保存到Rd中。指令格式如下:
EOR{cond}{S} Rd,Rn, operand2
(4). ARM数据处理指令:逻辑运算指令
应用示例:
EOR R1,R1,#0x0F ;将R1的低4位取反
EORS R0,R5,#0x01 ; 将R5和0x01进行逻辑异或,
;结果保存到R0,并影响标志位
助记符 说明 操作 条件码位置
AND Rd, Rn, operand2 逻辑与操作指令 Rd←Rn & operand2 AND{cond}{S}
ORR Rd, Rn, operand2 逻辑或操作指令 Rd←Rn | operand2 ORR{cond}{S}
EOR Rd, Rn, operand2 逻辑异或操作指令 Rd←Rn ^ operand2 EOR{cond}{S}
BIC Rd, Rn, operand2 位清除指令 Rd←Rn & (~operand2) BIC{cond}{S}
位清除指令——BIC指令将寄存器Rn的值与operand2的值的反码按位
作逻辑“与”操作,结果保存到Rd中。指令格式如下:
BIC{cond}{S} Rd,Rn, operand2
(4). ARM数据处理指令:逻辑运算指令
应用示例:
BIC R1,R1,#0x0F ;将R1的低4位清零,其它位不变
助记符 说明 操作 条件码位置
CMP Rn, operand2 比较指令
标志 N、 Z、 C、 V←Rn-
operand2
CMP{cond}
CMN Rn, operand2 负数比较指令
标 志 N、 Z、 C、
V←Rn+operand2
CMN{cond}
TST Rn, operand2 位测试指令
标志N、Z、C、V←Rn &
operand2
TST{cond}
TEQ Rn, operand2 相等测试指令
标志N、Z、C、V←Rn ^
operand2
TEQ{cond}
(4). ARM数据处理指令: 比较指令
助记符 说明 操作 条件码位置
CMP Rn, operand2 比较指令
标志 N、 Z、 C、 V←Rn-
operand2
CMP{cond}
CMN Rn, operand2 负数比较指令
标 志 N、 Z、 C、
V←Rn+operand2
CMN{cond}
TST Rn, operand2 位测试指令
标志N、Z、C、V←Rn &
operand2
TST{cond}
TEQ Rn, operand2 相等测试指令
标志N、Z、C、V←Rn ^
operand2
TEQ{cond}
比较指令——CMP指令将寄存器Rn的值减去operand2的值,根据操作
的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标
志来判断是否执行。指令格式如下:
CMP{cond} Rn, operand2
(4). ARM数据处理指令:比较指令
应用示例:
CMP R1,#10 ; R1与10比较,设置相关标志位
助记符 说明 操作 条件码位置
CMP Rn, operand2 比较指令
标志 N、 Z、 C、 V←Rn-
operand2
CMP{cond}
CMN Rn, operand2 负数比较指令
标 志 N、 Z、 C、
V←Rn+operand2
CMN{cond}
TST Rn, operand2 位测试指令
标志N、Z、C、V←Rn &
operand2
TST{cond}
TEQ Rn, operand2 相等测试指令
标志N、Z、C、V←Rn ^
operand2
TEQ{cond}
负数比较指令——CMN指令使用寄存器Rn的值加上operand2的值,
根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应
的条件标志来判断是否执行。指令格式如下:
CMP{cond} Rn, operand2
(4). ARM数据处理指令:比较指令
应用示例:
CMN R0,#1 ;R0+1,判断R0是否为1的补码。若是,则Z
;位置1。
注意:
CMN指令与ADDS指
令的区别在于CMN指令
不保存运算结果。
位。
助记符 说明 操作 条件码位置
CMP Rn, operand2 比较指令
标志 N、 Z、 C、 V←Rn-
operand2
CMP{cond}
CMN Rn, operand2 负数比较指令
标 志 N、 Z、 C、
V←Rn+operand2
CMN{cond}
TST Rn, operand2 位测试指令
标志N、Z、C、V←Rn &
operand2
TST{cond}
TEQ Rn, operand2 相等测试指令
标志N、Z、C、V←Rn ^
operand2
TEQ{cond}
位测试指令——TST指令将寄存器Rn的值与operand2的值按位作逻辑
“与”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后面的
指令根据相应的条件标志来判断是否执行。指令格式如下:
TST{cond} Rn, operand2
(4). ARM数据处理指令:比较指令
应用示例:
TST R0,#0x01 ; 判断R0的最低位是否为0
TST R1,#0x0F ; 判断R1的低4位是否为0
注意:
TST指令与ANDS指令
的区别在于TST指令不保存
运算结果。
TST指令通常与EQ、
NE条件码配合使用,当所有
测试位均为0时,EQ有效,
而只要有一个测试位不为0
,则NE有效。
助记符 说明 操作 条件码位置
CMP Rn, operand2 比较指令
标志 N、 Z、 C、 V←Rn-
operand2
CMP{cond}
CMN Rn, operand2 负数比较指令
标 志 N、 Z、 C、
V←Rn+operand2
CMN{cond}
TST Rn, operand2 位测试指令
标志N、Z、C、V←Rn &
operand2
TST{cond}
TEQ Rn, operand2 相等测试指令
标志N、Z、C、V←Rn ^
operand2
TEQ{cond}
相等测试指令——TEQ指令将寄存器Rn的值与operand2的值按位作逻
辑“异或”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后
面的指令根据相应的条件标志来判断是否执行。指令格式如下:
TEQ{cond} Rn, operand2
(4). ARM数据处理指令:比较指令
应用示例:
TEQR0,R1 ; 比较R0与R1是否相等 (不影响V位和C位
)
注意:
TEQ指令与EORS指令的
区别在于TEQ指令不保存运算
结
果。使用TEQ进行相等测试时,
常与EQ、NE条件码配合使用。
当两个
数据相等时,EQ有效;否则
NE有效。
(5).乘法指令
ARM7TDMI具有三种乘法指令,分别为:
32×32位乘法指令;
32× 32位乘加指令;
32× 32位结果为64位的乘/乘加指令。
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
UMULL{cond}{S
}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
UMLAL{cond}{S
}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
SMULL{cond}{S
}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
SMLAL{cond}{S
}
(5).乘法指令
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
UMULL{cond}{S
}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
UMLAL{cond}{S
}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
SMULL{cond}{S
}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
SMLAL{cond}{S
} 32位乘法指令——MUL指令将Rm和Rs中的值相乘,结果的低32位保
存到Rd中。指令格式如下:
MUL{cond}{S} Rd,Rm,Rs
(5).乘法指令
应用示例:
MUL R1,R2,R3 ;R1=R2×R3
MULS R0,R3,R7 ;R0=R3×R7,同时影响CPSR中的N位和Z位
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
UMULL{cond}{S
}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
UMLAL{cond}{S
}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
SMULL{cond}{S
}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
SMLAL{cond}{S
} 32位乘加指令——MLA指令将Rm和Rs中的值相乘,再将乘积加上第3
个操作数,结果的低32位保存到Rd中。指令格式如下:
MLA{cond}{S} Rd,Rm,Rs,Rn
(5).乘法指令
应用示例:
MLA R1,R2,R3,R0 ; R1=R2×R3+R0
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
UMULL{cond}{S
}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
UMLAL{cond}{S
}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
SMULL{cond}{S
}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
SMLAL{cond}{S
}
64位无符号乘法指令——UMULL指令将Rm和Rs中的值作无符号数相
乘,结果的低32位保存到RdLo中,而高32位保存到RdHi中。指令格式如
下:
UMULL{cond}{S} RdLo,RdHi,Rm,Rs
(5).乘法指令
应用示例:
UMLAL R0,R1,R5,R8 ;(R1、R0)=R5×R8+(R1、R0)
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
UMULL{cond}{S
}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
UMLAL{cond}{S
}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
SMULL{cond}{S
}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
SMLAL{cond}{S
} 64位无符号乘加指令——UMLAL指令将Rm和Rs中的值作无符号数相
乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,而高32
位保存到RdHi中。指令格式如下:
UMLAL{cond}{S} RdLo,RdHi,Rm,Rs
(5).乘法指令
应用示例:
UMULL R0,R1,R5,R8 ; (R1、R0)=R5×R8
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
UMULL{cond}{S
}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
UMLAL{cond}{S
}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
SMULL{cond}{S
}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
SMLAL{cond}{S
}
64位有符号乘法指令——SMULL指令将Rm和Rs中的值作有符号数相
乘,结果的低32位保存到RdLo中,而高32位保存到RdHi中。指令格式如
下:
SMULL{cond}{S} RdLo,RdHi,Rm,Rs
(5).乘法指令
应用示例:
SMLAL R2,R3,R7,R6 ; (R3、R2)=R7×R6+(R3、R2)
助记符 说明 操作 条件码位置
MUL Rd,Rm,Rs 32位乘法指令 Rd←Rm*Rs (Rd≠Rm) MUL{cond}{S}
MLA Rd,Rm,Rs,Rn 32位乘加指令 Rd←Rm*Rs+Rn (Rd≠Rm) MLA{cond}{S}
UMULL RdLo,RdHi,Rm,Rs 64位无符号乘法指令 (RdLo,RdHi) ←Rm*Rs
UMULL{cond}{S
}
UMLAL RdLo,RdHi,Rm,Rs 64位无符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
UMLAL{cond}{S
}
SMULL RdLo,RdHi,Rm,Rs 64位有符号乘法指令 (RdLo,RdHi) ←Rm*Rs
SMULL{cond}{S
}
SMLAL RdLo,RdHi,Rm,Rs 64位有符号乘加指令
(RdLo,RdHi)
←Rm*Rs+(RdLo,RdHi)
SMLAL{cond}{S
} 64位有符号乘加指令——SMLAL指令将Rm和Rs中的值作有符号数相乘,
64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,而高32位保
存到RdHi中。指令格式如下:
SMLAL{cond}{S} RdLo,RdHi,Rm,Rs
(5).乘法指令
应用示例:
SMULL R2,R3,R7,R6 ; (R3、R2)=R7×R6
(6). ARM分支指令
在ARM中有两种方式可以实现程序的跳转,一
种是使用分支指令直接跳转,另一种则是直接向PC
寄存器赋值实现跳转。 分支指令有以下三种:
分支指令B;
带链接的分支指令BL;
带状态切换的分支指令BX。
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4,PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label,切换处理器状态 BX{cond}
(6). ARM分支指令
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4,PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label,切换处理器状态 BX{cond}
分支指令——B指令,该指令跳转范围限制在当前指令的±32M字节地
址内(ARM指令为字对齐,最低2位地址固定为0)。指令格式如下:
B{cond} Label
(6). ARM分支指令
应用示例:
B WAITA ; 跳转到WAITA标号处
B 0x1234 ; 跳转到绝对地址0x1234处
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4,PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label,切换处理器状态 BX{cond}
带链接的分支指令——BL指令适用于子程序调用,使用该指令后,下
一条指令的地址被拷贝到R14(即LR) 连接寄存器中,然后跳转到指定地址运
行程序。跳转范围限制在当前指令的±32M字节地址内。指令格式如下:
BL{cond} Label
(6). ARM分支指令
应用示例:
BL DELAY ; 调用子程序DELAY
注意:
分支指令BL限制
在当前指令的±32
MB的范围内。BL指
令用于子程序调用。
助记符 说明 操作 条件码位置
B label 分支指令 PC←label B{cond}
BL label 带链接的分支指令 LR←PC-4,PC←label BL{cond}
BX Rm 带状态切换的分支指令 PC←label,切换处理器状态 BX{cond}
带 状 态 切 换 的 分 支 指 令 ——BX指 令 , 该 指 令 可 以 根 据 跳 转 地 址
(Rm)的最低位来切换处理器状态。其跳转范围限制在当前指令的±32M
字节地址内(ARM指令为字对齐,最低2位地址固定为0)。指令格式如下:
BX{cond} Rm
(6). ARM分支指令
应用示例:
ADRL R0,ThumbFun+1 ;将Thumb程序的入口地址加1
;存入R0
BX R0 ;跳转到R0指定的地址,并根据
;R0的最低位来切换处理器状态
助记符 说明 操作 条件码位置
CDP
coproc,opcode1,CRd,CRn,
CRm{,opcode2}
协处理器数据操作指令 取决于协处理器 CDP{cond}
LDC{L} coproc, CRd,<地址> 协处理器数据读取指令 取决于协处理器
LDC{cond}{L
}
STC{L} coproc, CRd,<地址> 协处理器数据写入指令 取决于协处理器
STC{cond}{L
}
MCR coproc,opcode1,Rd,CRn,
CRm{,opcode2}
ARM寄存器到协处理器寄
存器的数据传送指令
取决于协处理器 MCR{cond}
MRC coproc,opcode1,Rd,CRn,
CRm{,opcode2}
协处理器寄存器到ARM寄
存器到的数据传送指令
取决于协处理器 MCR{cond}
(7).协处理器指令
ARM处理器通过CDP指令通知ARM协处理器执行特定的操作。该操作
由协处理器完成,即对命令的参数的解释与协处理器有关,指令的使用取
决于协处理器。若协处理器不能成功地执行该操作,将产生未定义指令异
常中断。指令格式如下:
CDP{cond} coproc,opcode1,CRd,CRn,CRm{,opcode2}
应用示例:
CDP p7,0,c0,c2,c3,0 ;对协处理器7操作,操作码为0,
;可选操作码为0
CDP p6,1,c3,c4,c5 ;对协处理器6操作,操作码为1
(7).协处理器指令:数据操作指令
协处理器数据存取指令LDC/STC指令可以将某一连续内存单元的数据
读取到协处理器的寄存器中,或者将协处理器的寄存器数据写入到某一连
续的内存单元中,传送的字数由协处理器来控制。若协处理器不能成功地
执行该操作,将产生未定义指令异常中断。
LDC{cond}{L} coproc, CRd,<地址>
数据存储指令格式
STC{cond}{L} coproc, CRd,<地址>
数据读取指令格式
(7).协处理器指令:数据存取指令
协处理器数据存取指令LDC/STC指令可以将某一连续内存单元的数据
读取到协处理器的寄存器中,或者将协处理器的寄存器数据写入到某一连
续的内存单元中,传送的字数由协处理器来控制。若协处理器不能成功地
执行该操作,将产生未定义指令异常中断。
应用示例:
LDC p5,c2,[R2,#4]
LDC p6,c2,[R1]
STC p5,c1,[R0]
STC p5,cl,[R0,#-0x04]
数据操作指令编码
(7).协处理器指令:数据存取指令
如果需要在ARM处理器中的寄存器与协处理器中的寄存器之间进行数
据传送,那么可以使用MCR/MRC指令。MCR指令用于将ARM处理器的寄
存器中的数据传送到协处理器的寄存器。MRC指令用于将协处理器的寄存
器中的数据传送到ARM处理器的寄存器中。若协处理器不能成功地执行该
操作,将产生未定义指令异常中断。
MCR{cond} coproc,opcode1,Rd,CRn,CRm{,opcode2}
MRC指令格式(协处理器 ARM )
MCR指令格式(ARM协处理器)
MRC{cond} coproc,opcode1,Rd,CRn,CRm{,opcode2}
(7).协处理器指令:寄存器传送指令
如果需要在ARM处理器中的寄存器与协处理器中的寄存器之间进行数
据传送,那么可以使用MCR/MRC指令。MCR指令用于将ARM处理器的寄
存器中的数据传送到协处理器的寄存器。MRC指令用于将协处理器的寄存
器中的数据传送到ARM处理器的寄存器中。若协处理器不能成功地执行该
操作,将产生未定义指令异常中断。
寄存器传送指令编码
应用示例:
MCR p6,2,R7,c1,c2
MCR p7,0,R1,c3,c2,1
MRC p5,2,R2,c3,c2
MRC p7,0,R0,c1,c2,1
(7).协处理器指令:寄存器传送指令
(8).杂项指令
ARM指令集中有三条指令作为杂项指令,实际
上这三条指令非常重要。它们如下所示:
助记符 说明 操作 条件码位置
SWI immed_24 软中断指令 产生软中断,处理器进入管理模式 SWI{cond}
MRS Rd,psr 读状态寄存器指令 Rd←psr,psr为CPSR或SPSR MRS{cond}
MSR psr_fields,
Rd/#immed_8r
写状态寄存器指令
psr_fields←Rd/#immed_8r,psr为
CPSR或SPSR
MSR{cond}
(8).杂项指令:软中断指令
SWI指令用于产生软中断,从而实现在从户模式变换到管理模式,并
且将CPSR保存到管理模式的SPSR中,然后程序跳转到SWI异常入口。在其
它模式下也可使用SWI指令,处理器同样地切换到管理模式。
SWI{cond} immed_24
SWI指令格式:
指令举例如下:
SWI 0 ;软中断,中断立即数为0
SWI 0xl23456 ;软中断,中断立即数为0xl23456
使用SWI指令时,通常使用以下两种方法进行传递参数,SWI异常中
断处理程序就可以提供相关的服务。
这两种方法均由用户软件协定。
SWI异常中断处理程序要通过读取引起软中断的SWI指令,以取得24
位立即数。
指令中的24位立即数指定了用户请求的服务类型,参数通过通用寄存器
传递。
MOV R0,#34 ;设置子功能号为34
SWI 12 ;调用12号软中断
指令中的24位立即数被忽略,用户请求的服务类型由寄存器R0的值决
定,参数通过其它的通用寄存器传递。
MOV R0,#12 ;调用12号软中断
MOV R1,#34 ;设置子功能号为34
SWI 0
(8).杂项指令:软中断指令
在SWI异常中断处理程序中,取出SWI指令中立即数的步骤为:
首先确定引起软中断的SWI指令是ARM指令还是Thumb指令,这可通
过对SPSR访问得到;
然后取得该SWI指令的地址,这可通过访问LR寄存器得到;
接着读出该SWI指令,分解出立即数。
SWI_Handler
STMFD SP!, {R0-R3, R12, LR} ; 现场保护
MRS R0, SPSR ; 读取SPSR
STMFD SP!, {R0} ; 保存SPSR
TST R0, #0x20 ; 测试T标志位
LDRNEH R0, [LR,#-2] ; 若是Thumb指令,读取指令码(16位)
BICNE R0, R0, #0xFF00 ; 取得Thumb指令的8位立即数
LDREQ R0, [LR,#-4] ; 若是ARM指令,读取指令码(32位)
BICEQ R0, R0, #0xFF000000 ; 取得ARM指令的24位立即数
...
LDMFD SP!, {R0-R3, R12, PC}^; SWI异常中断返回
(8).杂项指令:软中断指令
(8).杂项指令:读状态寄存器指令
指令格式如下:
MRS{cond} Rd,psr
其中: Rd 目标寄存器。
Rd不允许为R15。
psr CPSR或SPSR。
指令举例如下:
MRS R1,CPSR ;将CPSR状态寄存器读取,保存到R1中
MRS R2,SPSR ;将SPSR状态寄存器读取,保存到R2中
注意:
在ARM处理器中,只
有MRS指令可以将状态寄
存器CPSR或SPSR读出到
通用寄存器中。
在ARM处理器中,只有MRS指令可以对状态寄存器CPSR
和SPSR进行读操作。通过读CPSR可以了解当前处理器的工
作状态。读SPSR寄存器可以了解到进入异常前的处理器状态。
(8).杂项指令:读状态寄存器指令
MRS与MSR配合使用,实现CPSR或SPSR寄存器的读一
修改一写操作,可用来进行处理器模式切换、允许/禁止
IRQ/FIQ中断等设置。
另外,当进程切换或允许异常中断嵌套时,也需要使用
MRS指令来读取SPSR状态值,并保存起来。
在ARM处理器中,只有MSR指令可以对状态寄存器CPSR和SPSR进行写
操作。与MRS配合使用,可以实现对CPSR或SPSR寄存器的读-修改-写操作,
可以切换处理器模式、或者允许/禁止IRQ/FIQ中断等。
MSR{cond} psr_fields,#immed_8rMSR指令格式1
MSR{cond} psr_fields,RmMSR指令格式2
(8).杂项指令:写状态寄存器指令
指令举例如下:
MSR CPSR—c,#0xD3 ;CPSR…0]=0xD3,即切换
;到管理模式
MSR CPSR—cxsf,R3 ;CPSR=R3
说明:
只有在特权模式下才能修改状态寄存器。
程序中不能通过MSR指令直接修改CPSR中的T控制位来实
现ARM状态/Thumb状态的切换,必须使用BX指令完成处
理器状态的切换(因为BX指令属分支指令,它会打断流水线
状态,实现处理器状态切换)。
MRS与MSR配合使用,实现CPSR或SPSR寄存器的读—修
改—写操作,可用来进行处理器模式切换、允许/禁止
IRQ/FIQ中断等设置。
(9).伪指令
ARM伪指令不属于ARM指令集中的指令,是为了编
程方便而定义的。伪指令可以像其它ARM指令一样使用,
但在编译时这些指令将被等效的ARM指令代替。
ARM伪指令有四条,
ADR伪指令、
ADRL伪指令、
LDR伪指令、
NOP伪指令。
(9).伪指令:ADR小范围地址读取伪指令
ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址
值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替
换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该
ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。
ADR{cond} register,expr
ADR伪指令格式
指令执行的条件码 加载的目标寄存器 地址表达式
地址表达式expr的取指范围:
当地址值不是字对齐时,其取指范围为-255~255;
当地址值是字对齐时,其取指范围为-1020~1020;
当地址值是16字节对齐时,其取指范围将更大。
伪指令举例如下:
LOOP MOV R1,#0xF0
ADR R2,LOOP ;将LOOP的地址放人R2
ADR R3,LOOP + 4
可以用ADR加载地址实现查表,
ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地
址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址 。在汇编编
译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能
用两条指令实现,则产生错误,编译失败。
ADRL{cond} register,expr
ADRL伪指令格式
指令执行的条件码 加载的目标寄存器 地址表达式
地址表达式expr的取指范围:
当地址值不是字对齐时,其取指范围为-64K~64K;
当地址值是字对齐时,其取指范围为-256K~256K;
当地址值是16字节对齐时,其取指范围将更大。
(9).伪指令:ADRL中等范围的地址读取
伪指令举例如下:
ADRL R0,DATA—BUF
ADRL R1,DATA—BUF+80
DATA—BUF
SPACE 100 ;定义100字节缓冲区
可以用ADRL加载地址,实现程序跳转
LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇
编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的
常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指
令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令
从文字池读出常量。
LDR{cond} register,=expr
LDR伪指令格式
指令执行的条件码 加载的目标寄存器 基于PC的地址表达式
或外部表达式
(9).伪指令: LDR大范围的地址读取
伪指令举例如下:
LDR R0,=0x12345678 ;加载32位立即数0x12345678
LDR R0,=DATA_BUF+60 ;加载DATA_BUF地址+60
…
LTORG ;声明文字池
…
(9).伪指令: LDR大范围的地址读取
注意:
1.从指令位置到文字池的偏移量
必须小于4KB;
2.与ARM指令的LDR相比,伪指
令的LDR的参数有“=”号。
NOP伪指令在汇编时将会被替代成ARM中的空操作,比如
可能为“MOV R0,R0”指令等。
NOP
NOP伪指令格式:
(9).伪指令:NOP空操作伪指令
3. Thumb指令集介绍
Thumb不是一个完整的体系结构,不能期望处理器只
执行Thumb指令而不支持ARM指令集。
因此,Thumb指令只需要支持通用功能,必要时可
以借助于完善的ARM指令集,比如,所有异常自动进入
ARM状态。
Thumb指令集可以看作是ARM指令压缩形式的子集,
是针对代码密度的问题而提出的,它具有16位的代码密度。
说明:
在编写Thumb指令时,先要使用伪指令CODEl6声
明,而且在ARM指令中要使用BX指令跳转到Thumb指令,
以切换处理器状态。
编写ARM指令时,则可使用伪指令CODE32声明。
Thumb指令集没有协处理器指令、信号量指令以及
访问CPSR或SPSR的指令,没有乘加指令及64位乘法指
令等,且指令的第二操作数受到限制;除了分支指令B有
条件执行功能外,其它指令均为无条件执行;大多数
Thumb数据处理指令采用2地址格式。
1. 分支指令:
Thumb指令集与ARM指令集的区别如下:
程序相对转移,特别是条件跳转与ARM代码下的跳转
相比,在范围上有更多的限制,转向子程序是无条件的转
移。
2. 数据处理指令:
数据处理指令是对通用寄存器进行操作。在大多数情况
下,操作的结果须放人其中一个操作数寄存器中,而不
是第3个寄存器中。
数据处理操作比ARM状态的更少。
访问寄存器R8~R15受到一定限制。
除MOV和ADD指令访问器R8~R15外,其它数据处理
指令总是更新CPSR中的ALU状态标志。
访问寄存器R8~R15的Thumb数据处理指令不能更新
CPSR中的ALU状态标志。
3.单寄存器加载和存储指令
4.多寄存器加载和存储指令
在Thumb状态下,单寄存器加载和存储指令只能访
问寄存器R0~R7。
LDM和STM指令可以将任何范围为R0~R7的寄存
器子集加载或存储,多寄存器加载和存储指令只有
LDMIA和STMIA指令。
PUSH和POP指令使用堆栈指令R13作为基址实
现满递减堆栈。
除R0~R7外,PUSH指令还可以存储连接寄存器
R14,并且POP指令可以加载程序指令PC。