ARM指令的基本格式
ARM指令的基本格式为:
<Opcode> {<Cond>} {S} <Rd> , <Rn> { , <Opcode2> }
其中,< >内的项是必需的,{ }内的项是可选的。
(1)Opcode项
Opcode是指令助记符,即操作码,说明指令需要执行的操作,在指令中是必需的。
(2)Cond项(command)
Cond项表明了指令的执行的条件,每一条ARM指令都可以在规定的条件下执行,每条ARM指令包含4位的条件码,位于指令的最高4位[31:28]。条件码共有16种,每种条件码用2个字符表示,这两个字符可以添加至指令助记符的后面,与指令同时使用。当指令的执行条件满足时,指令才被执行,否则指令被忽略。如果在指令后不写条件码,则使用默认条件AL(无条件执行)。
指令的条件码
条 件 码 |
助记符后缀 |
标 志 |
含 义 |
0000 |
EQ |
Z置位 |
相等equal |
0001 |
NE |
Z清零 |
不相等not equal |
0010 |
CS |
C置位 |
无符号数大于或等于Carry Set |
0011 |
CC |
C清零 |
无符号数小于 |
0100 |
MI |
N置位 |
负数minus |
0101 |
PL |
N清零 |
正数或零plus |
0110 |
VS |
V置位 |
溢出 |
0111 |
VC |
V清零 |
没有溢出 |
1000 |
HI |
C置位Z清零 |
无符号数大于high |
1001 |
LS |
Z置位C清零 |
无符号数小于或等于less |
1010 |
GE |
N等于V |
带符号数大于或等于 |
1011 |
LT |
N不等于V |
带符号数小于least |
1100 |
GT |
Z清零且(N等于V) |
带符号数大于great |
1101 |
LE |
Z清零或(N不等于V) |
带符号数小于或等于 |
1110 |
AL |
忽略 |
无条件执行all |
1111 |
|
|
|
条件码应用举例:
例:比较两个值大小,并进行相应加1处理,C语言代码为:
if ( a > b ) a++;
else b++;
对应的ARM指令如下(其中R0中保存a 的值,R1中保存b的值):
CMP R0, R1 ; R0与R1比较,做R0-R1的操作
ADDHI R0, R0, #1 ;若R0 > R1, 则R0 = R0 + 1
ADDLS R1, R1, #1 ; 若R0 <= R1, 则R1 = R1 + 1
CMP比较指令,用于把一个寄存器的内容和另一个寄存器的内容或一个立即数进行比较,同时更新CPSR中条件标志位的值。指令将第一操作数减去第二操作数,但不存储结果,只更改条件标志位。
CMP R1, R0 ;做R1-R0的操作。
CMP R1,#10 ;做R1-10的操作。
(3) S项(sign)
S项是条件码设置项,它决定本次指令执行的结果是否影响至CPSR寄存器的相应状态位的值。该项是可选的,使用时影响CPSR,否则不影响CPSR。
(4)Rd项(destination)
Rd是指令中的目标寄存器,它是必需的。根据指令的不同,有些指令中要求Rd必须有R0~R7之间,有些要求Rd必须在R0~R14之间,有些则没有特殊要求。
(5)Rn项
Rn是第一个操作数的寄存器,和Rd一样,不同的指令对其的使用有不同的要求。
(6)Opcode2项
Opcode2项是第二个操作数,在ARM指令中,该操作数有三种形式:立即数形式、寄存器Rm形式和寄存器加移位形式(Rm, shift)。
例如:
SUB R3, R1, #10
SUB R3, R1, R2
SUB R3, R1, R2, LSL #2
SUB R3, R1, R2, LSL R0
ARM指令详解
ARM指令集可分为以下6类:
l 跳转指令
l 数据处理指令
l 程序状态寄存器(PSR)处理指令
l 加载/存储指令
l 协处理器指令
l 异常产生指令
ARM指令及功能描述
助 记 符 |
指令功能描述 |
ADC |
带进位加法指令 |
ADD |
加法指令 |
AND |
逻辑与指令 |
B |
跳转指令 |
BIC |
位清零指令 |
BKPT |
软件断点 |
BL |
带返回的跳转指令 |
BLX |
带返回和状态切换的跳转指令 |
BX |
带状态切换的跳转指令 |
CDP |
协处理器数据操作指令 |
CMN |
取反比较指令 |
CMP |
比较指令 |
EOR |
逻辑异或指令 |
LDC |
存储器到协处理器的数据传输指令 |
LDM |
加载多个寄存器的指令 |
LDR |
存储器到寄存器的数据传输指令 |
MCR |
从ARM寄存器到协处理器寄存器的数据传输指令 |
MLA |
乘加运算指令 |
MOV |
数据传输指令 |
MRC |
从协处理器寄存器到ARM寄存器的数据传输指令 |
MRS |
传送CPSR或SPSR的值到通用寄存器的指令 |
MSR |
传送通用寄存器的值到CPSR或SPSR的指令 |
MUL |
32位乘法指令 |
MVN |
数据取反传送指令 |
ORR |
逻辑或指令 |
RSB |
反向减法指令 |
RSC |
带借位的反向减法指令 |
SBC |
带借位的减法指令 |
STC |
协处理器寄存器写入存储器指令 |
STM |
存储多个寄存器的值到存储器指令 |
STR |
存储寄存器的值到存储器的指令 |
SUB |
减法指令 |
SWI |
软件中断指令 |
SWP |
寄存器与存储器 或 寄存器与寄存器之间的数据交换指令 |
TEQ |
相等测试指令 |
TST |
位测试指令 |
1. 跳转指令
用于实现程序流程的跳转,在ARM程序中有两种方法可以实现程序流程的跳转:一是使用专门的跳转指令,二是直接向程序计数器PC写入跳转地址值。第二种方法可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用“MOV LR , PC”等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。
1)ARM指令集中的跳转指令可以实现从当前指令向前或向后的32MB的地址空间的跳转。
l B指令
格式:
B{条件} 目标地址
注意,存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(相对寻址)。这个偏移量是一个24位的有符号数,左移两位后表示的有效偏移为26位(前后32MB的地址空间)。{}表示可以省略。
如:B Label 程序无条件跳转到标号Label处执行。
CMP R1,#0
BEQ Label
当CPSR寄存器中的Z条件码置位时,程序跳转到Label处执行。
当前PC:是指跳转指令本身的起始地址。
l BL指令
格式:
BL{条件} 目标地址
这条指令在跳转之前,会在寄存器R14中保存当前的下一条指令的地址,因此,可以通过将R14重新加载到PC中,来返回到跳转指令之后的那条指令处执行。该指令是实现子程序调用的一种常用手段。
l BX 指令
格式:
BX {条件} 目标地址
BX指令中所指定的目标地址,只能使用寄存器的寻址方式,即跳转的目标地址应先保存在一个寄存器中。指令在实现跳转的同时,完成处理器的工作状态的切换(ARM状态与Thumb状态间的切换)。
BX指令中,用寄存器的最低位来指示切换到哪一个工作状态。如寄存器最低位为1,则把目标地址处的代码解释为Thumb代码,进入Thumb工作状态,并自动将CPSR中的控制位T置1。若寄存器最低位为0,则把目标地址处的代码解释为ARM代码,进入ARM工作状态,并自动将CPSR中的控制位T置0。
…
ADRL R0, ThumbFun + 1 ;生成分支地址并置最低位为 1
BX R0 ;跳转到R0所指定的地址,并切换处理器到Thumb工作状态
…
ThumbFun
… ;Thumb汇编指令
…
| BLX指令
以上两条指令的综合。
2. 数据处理指令
数据处理指令可分数据传送指令、算术逻辑运算指令和比较指令等。数据传送指令用于在寄存器和存储器之间进行数据的双向的传输。所有ARM数据处理指令均可选择使用S后缀,以影响状态标志CPSR。比较指令(CMP、CMN、TST、TEQ)不保存运算结果,这些指令也不使用S后缀,但会直接影响CPSR中的相应的状态标志位。
(1)数据传送指令MOV 和MVN
格式:
MOV {条件} {S} 目的寄存器, 源操作数
MOV指令可以完成从另一个寄存器、被移位的寄存器、或将一个立即数加载到目的寄存器。与MVN指令不同的是在传送之前,将被传送的对象先按位取反,再传送到目的寄存器。
例:MVN R1 , #0XFF ;R1 ← 0X FFFF FF00
MVN R1 , R2
MOV PC,R14;将寄存器R14的值传送给PC,用于子程序返回。
(2) 数据比较指令CMP , CMN , TST , TEQ
例:
CMP R1, R2 ; 做R1 – R2 的操作,结果不保存,但影响标志位。
CMP R1 , #10 ;做R1 - 10的操作,结果不保存,但影响标志位。
CMN 指令用于把一个寄存器的内容和另一个寄存器的内容或立即数取反后进行比较操作,根据运算结果影响CPSR中的标志位。该指令实际完成操作数1和操作数2相加,并根据结果更改条件标志位。
TST位测试指令,用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的与运算,并根据运算结果更新CPSR中条件标志位的值。操作数1是要测试的数,而操作数2 是一个位掩码,该指令一般用来检测是否设置了特定的位。
TST {条件} 操作数1, 操作数2
例:TST R0, #0X0000 0040 ; 指令用来测试R0的位3是否为1。
TST指令通常和EQ、NE条件码配合使用,当所有测试位为0时,EQ有效,而只要有一个测试位不为0,则NE有效。
TEQ相等测试指令,用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的异或运算,并根据运算结果更新CPSR中的条件标志位。指令用于比较两个操作数是否相等。如果相等,则 Z = 1,否则Z = 0。指令通常和EQ、NE条件码配合使用
例:TEQ R1, R2
TST R1,#%1;测试R1中是否设置了最低位(%表示二进制数)
(3)逻辑运算类指令:AND、ORR、EOR、BIC
格式:逻辑类指令 {条件} {S} 目的寄存器,操作数1, 操作数2
S选项,说明运算结果影响CPSR的条件标志位,没有S选项,则不影响CPSR的条件标志位。
操作数1应该是一个寄存器,操作数2可以是一个寄存器、被移位的寄存器或一个立即数。
AND指令常用于将操作数1的某个位置0;ORR指令常用于将操作数1的某个位置1;EOR(异或)指令常用于将操作数1的某个位取反。与0相异或,保持不变,与1相异或,则取反。BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中,如果在掩码中设置了某一位,则清除这一位。未设置的掩码位保持不变。
例:BIC R1, R1, #0X0F ;将R1的低四位清零,其他位不变。
(4)算术运算类指令:ADD、ADC、SUB、SBC、RSB、RSC
格式:算术运算类指令 {条件} {S} 目的寄存器,操作数1,操作数2
目的寄存器,操作数1和操作数2使用的寄存器必须在R0~R7之间。
操作数1应该是一个寄存器,操作数2可以是一个寄存器、被移位的寄存器或一个立即数。
例:ADDS R1, R1,#10 ;结果影响标志位
ADD R1, R1, R2 ;结果不影响标志位
ADD R3, R1, R2, LSL #2 ; R3 = R1 + ( R2 << 2 )
ADD指令完成的功能是将操作数1加上操作数2,结果送到目的寄存器。
ADC指令完成的功能是将操作数1加上操作数2,再加上标志位C的值,结果送到目的寄存器。
SUB指令完成的功能是将操作数1减去操作数2,结果送到目的寄存器。
SBC指令完成的功能是将操作数1减去操作数2,再减去标志位C的取反值,结果送到目的寄存器。
RSB逆向减法指令完成的功能是将操作数2减去操作数1,结果送到目的寄存器。
RSC带借位的逆向减法指令完成的功能是将操作数2减去操作数1,再减去标志位C的取反值,结果送到目的寄存器。
例:
SUB R0, R1, #256 ;R0 = R1 - 256 , 结果不影响标志位
SUBS R0, R2,R3,LSL #1 ;R0 = R2 - ( R3 <<1 ),结果影响标志位
SUB SP , #380 ;SP = SP - 380
SBC R0, R1, R2 ;R0 = R1 - R2 - !C
RSC R0, R1, R2 ;R0 = R2 - R1 - !C
(5)乘法指令与乘加指令
ARM微处理器支持的乘法指令与乘加指令共有6条,可分为运算结果为32位和结果为64位两类,与前面的数据处理指令不同,指令中的所有操作数、目的寄存器必须为通用寄存器,不能对操作数使用立即数或被移位的寄存器,同时,目的寄存器和操作数1必须是不同的寄存器。
l MUL指令
格式:
MUL {条件} {S} 目的寄存器,操作数1, 操作数2
功能:
目的寄存器 = 操作数1 × 操作数2,同时可以根据运算结果设置CPSR中相应的条件标志位N和Z。操作数1和操作数2均为32位的有符号数或无符号数。
l MLA指令
格式:
MLA {条件} {S} 目的寄存器,操作数1, 操作数2, 操作数3
功能:
目的寄存器 = 操作数1 × 操作数2 + 操作数3,同时可以根据运算结果设置CPSR中相应的条件标志位N和Z。操作数1和操作数2均为32位的有符号数或无符号数。
l SMULL指令(S:Signed, 有符号)
格式:
SMULL {条件} {S} 目的寄存器Low,目的寄存器High,操作数1, 操作数2
功能:
目的寄存器Low = (操作数1 × 操作数2 )的低32位,
目的寄存器High = (操作数1 × 操作数2 )的高32位,同时可以根据运算结果设置CPSR中相应的条件标志位。操作数1和操作数2均为32位的有符号数。
例:
SMULL R0, R1, R2, R3
;R0 = (R2 ×R3)的低32位, R1 = (R2 ×R3)的高32位。
l SMLAL指令(S:Signed, 有符号)
格式:
SMLAL {条件} {S} 目的寄存器Low,目的寄存器High,操作数1, 操作数2
功能:
目的寄存器Low = (操作数1 × 操作数2 )的低32位 + 目的寄存器Low,
目的寄存器High = (操作数1 × 操作数2 )的高32位 + 目的寄存器High,同时可以根据运算结果设置CPSR中相应的条件标志位。操作数1和操作数2均为32位的有符号数。
例:
SMLAL R0, R1, R2, R3
;R0 = (R2 ×R3)的低32位 + R0,
;R1 = (R2 ×R3)的高32位 + R1。
l UMULL指令(U:UnSigned, 无符号)
格式:
UMULL {条件} {S} 目的寄存器Low,目的寄存器High,操作数1, 操作数2
功能:
目的寄存器Low = (操作数1 × 操作数2 )的低32位,
目的寄存器High = (操作数1 × 操作数2 )的高32位,同时可以根据运算结果设置CPSR中相应的条件标志位。操作数1和操作数2均为32位的无符号数。
例:
UMULL R0, R1, R2, R3
;R0 = (R2 ×R3)的低32位, R1 = (R2 ×R3)的高32位。
l UMLAL指令(U:UnSigned, 无符号)
格式:
UMLAL {条件} {S} 目的寄存器Low,目的寄存器High,操作数1, 操作数2
功能:
目的寄存器Low = (操作数1 × 操作数2 )的低32位 + 目的寄存器Low,
目的寄存器High = (操作数1 × 操作数2 )的高32位 + 目的寄存器High,同时可以根据运算结果设置CPSR中相应的条件标志位。操作数1和操作数2均为32位的无符号数。
例:
UMLAL R0, R1, R2, R3
;R0 = (R2 ×R3)的低32位 + R0,
;R1 = (R2 ×R3)的高32位 + R1。
3. 程序状态寄存器访问指令
功能:用于在程序状态寄存器和通用寄存器之间传送数据。
l MRS指令
格式:
MRS {条件} 通用寄存器, 程序状态寄存器(CPSR、SPSR)
功能:
将状态寄存器的内容传送到通用寄存器。
使用环境:
(1)当需要改变程序状态寄存器的内容时,可用MRS将状态寄存器的内容读入到通用寄存器,修改后再写回到程序状态寄存器。
(2)当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。
l MSR指令
格式:
MSR {条件} 程序状态寄存器(CPSR、SPSR)_<域>,操作数
功能:
将操作数的内容传送到程序状态寄存器的特定域中。其中,操作数可以为通用寄存器或立即数。<域>用于设置程序状态寄存器中需要操作的位,32位的程序状态寄存器分为4个域:
F域:位31~位24为条件标志位域;
S域:位23~位16为状态位域;
X域:位15~位8为扩展位域;
C域:位7~位0为控制位域;
使用环境:
(1)当需要改变程序状态寄存器的内容时,可用MRS将状态寄存器的内容读入到通用寄存器,修改后再写回到程序状态寄存器。
(2)当在异常处理或进程切换时,需要保存程序状态寄存器的值,可先用该指令读出程序状态寄存器的值,然后保存。
例:
MSR CPSR , R0 ;CPSR←R0
MSR SPSR_c , R0 ;传送R0到SPSR,但仅修改SPSR中的控制位域
MSR CPSR_c , #0XD3 ; CPSR[7..0] = 0XD3 , 即切换到管理模式
MSR CPSR_cxsf , R3 ; CPSR ← R3
注意:只有在特权模式下,才能修改状态寄存器。
程序中不能通过MSR指令直接修改CPSR中的T控制位来实现ARM/Thumb状态的切换,必须使用BX指令来完成处理器状态的切换。
MRS与MSR配合使用,可以实现CPSR或SPSR寄存器的读/修改/写操作,进行处理器模式 切换,进行允许/禁止IRQ/FIQ中断等的设置。
例:使能IRQ中断
MRS R0 , CPSR
BIC R0 , R0 , #0X80
MSR CPSR_c , R0
MOV PC , LR
例:禁止IRQ中断
MRS R0 , CPSR
ORR R0 , R0 , #0X80
MSR CPSR_c , R0
MOV PC , LR
4. 存储器加载/存储指令
功能:用于在寄存器和存储器之间传送数据,加载指令用于将存储器中的数据传送到寄存器,存储指令则将寄存器中的数据传送到存储器。
存储器加载/存储指令分为单个存储器加载/存储指令和多个存储器加载/存储指令。
(1)单个存储器加载/存储指令
LDR字数据加载指令;
LDRH(Half)半字数据加载指令;
LDRB字节数据加载指令;
STR字数据存储指令;
STRH半字数据存储指令;
STRB字节数据存储指令。
l 加载指令
格式:
加载指令 {条件} 目的寄存器, <存储器地址>
例:
LDR R0 , [R1] ;将地址为R1的字数据读入R0。
LDR R0 , [R1,R2] ;将地址为R1+R2的字数据读入R0。
LDR R0 , [R1, #4] ;将地址为R1+4的字数据读入R0。
LDR R0 , [R1, R2]! ;将地址为R1+R2的字数据读入R0,并将新地址R1+R2写入R1。
LDR R0 , [R1, R2, LSL #2 ] !
;将地址为R1 + R2 × 4的字数据读入R0,并将新地址R1 + R2 × 4写入R1。
LDRH指令用于从存储器中将一个16位的半字数据传送到目的寄存器中,同时将寄存器的高16位清零。
LDRH R0 , [R1] ;将地址为R1的半字数据读入R0,并将R0的高16位清零。
LDRB指令用于从存储器中将一个8位的字节数据传送到目的寄存器中,同时将寄存器的高24位清零。
LDRB R0 , [R1] ;将地址为R1的字节数据读入R0,并将R0的高24位清零。
注意:当是字操作时,操作数的地址必须是字对齐的,如果是半字操作,操作数的地址必须是半字对齐。否则,读出的数据是无效,随机的。
例:
LDR R0 , [R1 , # 2 ]
LDRH R0 , [R1 , # 1 ]
l 存储指令
格式:
存储指令 {条件} 源寄存器, <存储器地址>
例:
STR R0 , [R1] , #8
;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1。
STR R0 , [R1 , #8] ;将R0中的字数据写入以R1+8为地址的存储器中。
STRH指令用于从源寄存器中将一个16位的半字数据传送到存储器中。该半字数据为源寄存器中的低16位。
STRH R0 , [R1, #8] ;将寄存器R0中的低16位写入以R1 + 8为地址的存储器中。
STRB指令用于从源寄存器中将一个8位的字节数据传送到存储器中。该字节数据为源寄存器中的低8位。
注意:当是字操作时,操作的地址必须是字对齐的,如果是半字操作,操作的地址必须是半字对齐。否则,读出的数据是无效,随机的。
(2)批量数据加载/存储指令
功能:可以一次在一片连续的存储器单元和多个寄存器之间传送数据,批量加载指令用于将一片连续的存储器中的数据传送到多个寄存器,批量数据存储指令完成相反的操作。
LDM(或STM)指令(Load Data To Multiple Register)
格式:
LDM(或STM) {条件} {类型} 基址寄存器{!} ,寄存器列表{^}
{类型}为以下几种情况:
类 型 |
含 义 |
IA |
每次操作后,地址加4 |
IB |
每次操作前,地址加4 |
DA |
每次操作后,地址减4 |
DB |
每次操作前,地址减4 |
FD |
满递减堆栈 |
ED |
空递减堆栈 |
FA |
满递增堆栈 |
EA |
空递增堆栈 |
{!}为可选后缀,若选用,则当数据传送完毕之后,将最后的地址写入基址寄存器,否则基址寄存器的内容不改变。
基址寄存器不允许为R15,寄存器列表可以为R0 ~ R15的任意组合。
{^}为可选后缀,当指令为LDM且寄存器列表中包含有R15,选用该后缀表示:除了正常的数据传送之外,还将SPSR复制到CPSR。同时,该后缀还表示传入或付传出的是用户模式下的寄存器,而不是当前模式下的寄存器。
例:
STMFD SP!, {R0 - R7 , LR} ;现场保存,将R0 - R7 , LR入栈,满递减堆栈。
LDMFD SP!, {R0 - R7 , PC}^ ;恢复现场,异常处理返回,满递减堆栈
在进行数据复制时,先设置好源数据指针,然后使用块拷贝寻址指令进行读取和存储。而在堆栈操作中,则要先设置堆栈指针SP,然后使用堆栈寻址指令实现堆栈操作。
5. 数据交换指令
功能:支持在存储器和寄存器之间交换数据。
SWP ( Swap ) 字数据交换指令;
SWPB 字节数据交换指令。
格式:
交换指令 {条件} 目的寄存器, 源寄存器1, [源寄存器2]
例:
SWP R0, R1, [R2] ;将R2所指的存储器中的字数据传送到R0,同时将R1中的字数据传送到R2所指的存储器单元。
显然,当源寄存器1与目的寄存器是同一个寄存器时,就完成了寄存器与存储器间的交换操作。
SWPB指令用于将源寄存器2所指向的存储器中的字节数据到目的寄存器中,目的寄存器的高24位清零,同时将源寄存器1中的低8位数据(低位字节)传送到源寄存器2所指向的存储器中。
6. 异常产生指令
异常指令有两条:SWI软件中断指令和BKPT断点中断指令。
l SWI中断指令
格式:
SWI {条件} 24位的立即数
功能:
产生软件中断,方便用户程序调用操作系统的系统例程。
操作:
切换运行模式到管理模式,设置PC来执行在地址0X08处的下一条指令,设置相应的R13_svc和R14_svc。该指令的操作与执行BL 0X08这条指令的效果是相同的。不同的地方在于,SWI还带有指明系统例程的类型的“24位的立即数”。在具体应用中,为便于记忆,可以使用字符串代替“24位的立即数”,例如:SWI “OS_Write0”和 SWI 0X02是一样的。当指令中24位的立即数被忽略时,系统例程的类型由通用寄存器R0的内容决定。传送给系统例程的参数通过通用寄存器来传递。
l BKPT指令
格式:
BKPT 16位的立即数
功能:
用于产生软件断点中断,执行时中断正常指令,进入相应的调试子程序。
7. 协处理器指令
ARM处理器可支持多达16个协处理器,每个协处理器只执行针对其自身的协处理指令。ARM的协处理器指令主要用于ARM处理器初始化、协处理器的数据处理操作、在ARM处理器与协处理器的寄存器之间传送数据、在协处理器和存储器之间传送数据。ARM协处理器指令有以下5条:
l CDP协处理器数据操作指令;
l LDC协处理器数据加载指令;
l STC协处理器数据存储指令;
l MCR ARM处理器寄存器到协处理器寄存器的数据传送指令;
l MRC 协处理器寄存器到ARM处理器寄存器的数据传送指令。
(1)CDP指令
格式:
CDP {条件}协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,源寄存器2,协处理器操作码2
功能:用于ARM处理器通知协处理器执行特定的操作,若协处理器不能执行指定的操作,则产生未定义指令异常。
注意:指令中涉及到的寄存器都是协处理器的寄存器,不涉及ARM处理器的寄存器和存储器。操作码1、操作码2是协处理器要执行的操作。
例: CDP p5 , 1 , c3 , c4 , c5 , 2
;指示协处理器P5,执行操作1,可选操作为2;C3, C4, C5是相应的协处理器寄存器。
(2) LDC指令
格式:
LDC {条件}{L}协处理器编码,目的寄存器,[源寄存器]
功能:
用于将源寄存器所指向的存储器中的字数据传送到目的寄存器中。若协处理器不能成功执行,则产生未定义指令异常。选项{L}表示指令为长读取操作,可用于双精度数据的传输。
注意:指令中涉及到的源寄存器是ARM处理器的寄存器。
例:LDC P3, C4, [R2, #4]
(3) STC指令
格式:
STC {条件}{L}协处理器编码,源寄存器,[目的寄存器]
功能:
用于将源寄存器中的字数据传送到目的寄存器所指向的存储器中。若协处理器不能成功执行,则产生未定义指令异常。选项{L}表示指令为长读取操作,可用于双精度数据的传输。
注意:指令中涉及到的目的寄存器是ARM处理器的寄存器。
例:STC P3, C4, [R0]
;将协处理器P3的寄存器C4中的数据传送到ARM处理器的寄存器R0所指向的存储器.
(4) MCR指令
格式:
MCR {条件}协处理器编码,协处理器操作码1,源寄存器,目的寄存器1,目的寄存器2,协处理器操作码2
功能:
MCR指令用于将ARM处理器寄存器中的数据传送到协处理器的寄存器中。若协处理器不能完成这个操作,将引发未定义指令异常。源寄存器为ARM处理器的寄存器。
(5) MRC指令
格式:
MRC {条件}协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,源寄存器2,协处理器操作码2
功能:
MRC指令用于将协处理器寄存器中的数送到ARM处理器的寄存器中。若协处理器不能完成这个操作,将引发未定义指令异常。源寄存器为ARM处理器的寄存器。
例:MRC P3 , 3 , R0 , C4 , C5 , 6
;将协处理器P3的寄存器C4与C5中的数据传送到ARM的寄存器中,并执行编号为3和6的操作。
Thumb指令集合
Thumb指令集是ARM指令集的一个子集,允许指令编码为16位的长度,Thumb指令集在保留32位代码优势的同时,大大节省了系统的存储空间。
当处理器在执行ARM程序段时,称ARM处理器处于ARM工作状态,当处理器在执行Thumb程序段时,称ARM处理器处于Thumb工作状态。
在编写Thumb指令时,先要用伪指令CODE16声明以下为Thumb指令代码,在ARM指令代码中可以使用BX指令跳转到Thumb指令代码片。同样编写ARM代码时,则使用伪指令CODE32进行声明,在Thumb指令代码中使用BX指令可以跳转到ARM指令代码处。
大多数Thumb指令是无条件执行的,而几乎所有的ARM指令都是有条件执行的。由于Thumb数据处理指令中的目的寄存器与其中的一个源寄存器相同,Thumb指令在指令编码时由三个操作数改为两个操作数。
通常实现同样的程序功能时,所需的Thumb指令的条数比ARM指令多。但使用Thumb指令集合的代码有以下特点:
l 比ARM代码更节略存储空间。
l 使用的指令条数比ARM代码多。
l 若使用32位的存储器,ARM代码比Thumb代码快约40%。
l 若使用16位的存储器,Thumb代码比ARM代码快约40%~50%。
l 与ARM代码相比较,使用Thumb代码,存储器的功耗会降低约30%。