第3章 ARM微处理器的指令系统.docx
- 文档编号:12587398
- 上传时间:2023-04-20
- 格式:DOCX
- 页数:34
- 大小:29.75KB
第3章 ARM微处理器的指令系统.docx
《第3章 ARM微处理器的指令系统.docx》由会员分享,可在线阅读,更多相关《第3章 ARM微处理器的指令系统.docx(34页珍藏版)》请在冰豆网上搜索。
第3章ARM微处理器的指令系统
第3章ARM微处理器的指令系统
本章介绍ARM指令集、Thumb指令集,以及各类指令对应的寻址方式,通过对本章的阅读,希望读者能了解ARM微处理器所支持的指令集及具体的使用方法。
本章的主要内容有:
-ARM指令集、Thumb指令集概述。
-ARM指令集的分类与具体应用。
-Thumb指令集简介及应用场合。
3.1ARM微处理器的指令集概述
3.1.1ARM微处理器的指令的分类与格式
ARM微处理器的指令集是加载/存储型的,也即指令集仅能处理寄存器中的数据,而且处理结果都要放回寄存器中,而对系统存储器的访问则需要通过专门的加载/存储指令来完成。
ARM微处理器的指令集可以分为跳转指令、数据处理指令、程序状态寄存器(PSR)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类,具体的指令及功能如表3-1所示(表中指令为基本ARM指令,不包括派生的ARM指令)。
表3-1ARM指令及功能描述
助记符
指令功能描述
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.2ARM指令的寻址方式
所谓寻址方式就是处理器根据指令中给出的地址信息来寻找物理地址的方式。
目前ARM指令系统支持如下几种常见的寻址方式。
3.2.1立即寻址
立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就在指令中给出,只要取出指令也就取到了操作数。
这个操作数被称为立即数,对应的寻址方式也就叫做立即寻址。
例如以下指令:
ADDR0,R0,#1;R0←R0+1
ADDR0,R0,#0x3f;R0←R0+0x3f
在以上两条指令中,第二个源操作数即为立即数,要求以“#”为前缀,对于以十六进制表示的立即数,还要求在“#”后加上“0x”或“&”。
3.2.2寄存器寻址
寄存器寻址就是利用寄存器中的数值作为操作数,这种寻址方式是各类微处理器经常采用的一种方式,也是一种执行效率较高的寻址方式。
以下指令:
ADDR0,R1,R2;R0←R1+R2
该指令的执行效果是将寄存器R1和R2的内容相加,其结果存放在寄存器R0中。
3.2.2寄存器间接寻址
寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身存放在存储器中。
例如以下指令:
ADDR0,R1,[R2];R0←R1+[R2]
LDRR0,[R1];R0←[R1]
STRR0,[R1];[R1]←R0
在第一条指令中,以寄存器R2的值作为操作数的地址,在存储器中取得一个操作数后与R1相加,结果存入寄存器R0中。
第二条指令将以R1的值为地址的存储器中的数据传送到R0中。
第三条指令将R0的值传送到以R1的值为地址的存储器中。
3.2.3基址变址寻址
基址变址寻址就是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。
变址寻址方式常用于访问某基地址附近的地址单元。
采用变址寻址方式的指令常见有以下几种形式,如下所示:
LDRR0,[R1,#4];R0←[R1+4]
LDRR0,[R1,#4]!
;R0←[R1+4]、R1←R1+4
LDRR0,[R1],#4;R0←[R1]、R1←R1+4
LDRR0,[R1,R2];R0←[R1+R2]
在第一条指令中,将寄存器R1的内容加上4形成操作数的有效地址,从而取得操作数存入寄存器R0中。
在第二条指令中,将寄存器R1的内容加上4形成操作数的有效地址,从而取得操作数存入寄存器R0中,然后,R1的内容自增4个字节。
在第三条指令中,以寄存器R1的内容作为操作数的有效地址,从而取得操作数存入寄存器R0中,然后,R1的内容自增4个字节。
在第四条指令中,将寄存器R1的内容加上寄存器R2的内容形成操作数的有效地址,从而取得操作数存入寄存器R0中。
3.2.4多寄存器寻址
采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。
这种寻址方式可以用一条指令完成传送最多16个通用寄存器的值。
以下指令:
LDMIAR0,{R1,R2,R3,R4};R1←[R0]
;R2←[R0+4]
;R3←[R0+8]
;R4←[R0+12]
该指令的后缀IA表示在每次执行完加载/存储操作后,R0按字长度增加,因此,指令可将连续存储单元的值传送到R1~R4。
3.2.5相对寻址
与基址变址寻址方式相类似,相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。
以下程序段完成子程序的调用和返回,跳转指令BL采用了相对寻址方式:
BLNEXT;跳转到子程序NEXT处执行
……
NEXT
……
MOVPC,LR;从子程序返回
3.2.6堆栈寻址
堆栈是一种数据结构,按先进后出(FirstInLastOut,FILO)的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。
当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(FullStack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(EmptyStack)。
同时,根据堆栈的生成方式,又可以分为递增堆栈(AscendingStack)和递减堆栈(DecendingStack),当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。
这样就有四种类型的堆栈工作方式,ARM微处理器支持这四种类型的堆栈工作方式,即:
-满递增堆栈:
堆栈指针指向最后压入的数据,且由低地址向高地址生成。
-满递减堆栈:
堆栈指针指向最后压入的数据,且由高地址向低地址生成。
-空递增堆栈:
堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成。
-空递减堆栈:
堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成。
3.3ARM指令集
本节对ARM指令集的六大类指令进行详细的描述。
3.3.1跳转指令
跳转指令用于实现程序流程的跳转,在ARM程序中有两种方法可以实现程序流程的跳转:
—使用专门的跳转指令。
—直接向程序计数器PC写入跳转地址值。
通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用
MOVLR,PC
等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。
ARM指令集中的跳转指令可以完成从当前指令向前或向后的32MB的地址空间的跳转,包括以下4条指令:
—B跳转指令
—BL带返回的跳转指令
—BLX带返回和状态切换的跳转指令
—BX带状态切换的跳转指令
1、B指令
B指令的格式为:
B{条件}目标地址
B指令是最简单的跳转指令。
一旦遇到一个B指令,ARM处理器将立即跳转到给定的目标地址,从那里继续执行。
注意存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。
它是24位有符号数,左移两位后有符号扩展为32位,表示的有效偏移为26位(前后32MB的地址空间)。
以下指令:
BLabel;程序无条件跳转到标号Label处执行
CMPR1,#0;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行
BEQLabel
2、BL指令
BL指令的格式为:
BL{条件}目标地址
BL是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容,因此,可以通过将R14的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。
该指令是实现子程序调用的一个基本但常用的手段。
以下指令:
BLLabel;当程序无条件跳转到标号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中条件标志位的值。
指令示例:
MOVR1,R0;将寄存器R0的值传送到寄存器R1
MOVPC,R14;将寄存器R14的值传送到PC,常用于子程序返回
MOVR1,R0,LSL#3;将寄存器R0的值左移3位后传送到R1
2、MVN指令
MVN指令的格式为:
MVN{条件}{S}目的寄存器,源操作数
MVN指令可完成从另一个寄存器、被移位的寄存器、或将一个立即数加载到目的寄存器。
与MOV指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到目的寄存器中。
其中S决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。
指令示例:
MVNR0,#0;将立即数0取反传送到寄存器R0中,完成后R0=-1
3、CMP指令
CMP指令的格式为:
CMP{条件}操作数1,操作数2
CMP指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行比较,同时更新CPSR中条件标志位的值。
该指令进行一次减法运算,但不存储结果,只更改条件标志位。
标志位表示的是操作数1与操作数2的关系(大、小、相等),例如,当操作数1大于操作操作数2,则此后的有GT后缀的指令将可以执行。
指令示例:
CMPR1,R0;将寄存器R1的值与寄存器R0的值相减,并根据结果设置CPSR的标志位
CMPR1,#100;将寄存器R1的值与立即数100相减,并根据结果设置CPSR的标志位
4、CMN指令
CMN指令的格式为:
CMN{条件}操作数1,操作数2
CMN指令用于把一个寄存器的内容和另一个寄存器的内容或立即数取反后进行比较,同时更新CPSR中条件标志位的值。
该指令实际完成操作数1和操作数2相加,并根据结果更改条件标志位。
指令示例:
CMNR1,R0;将寄存器R1的值与寄存器R0的值相加,并根据结果设置CPSR的标志位
CMNR1,#100;将寄存器R1的值与立即数100相加,并根据结果设置CPSR的标志位
5、TST指令
TST指令的格式为:
TST{条件}操作数1,操作数2
TST指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的与运算,并根据运算结果更新CPSR中条件标志位的值。
操作数1是要测试的数据,而操作数2是一个位掩码,该指令一般用来检测是否设置了特定的位。
指令示例:
TSTR1,#%1;用于测试在寄存器R1中是否设置了最低位(%表示二进制数)
TSTR1,#0xffe;将寄存器R1的值与立即数0xffe按位与,并根据结果设置CPSR的标志位
6、TEQ指令
TEQ指令的格式为:
TEQ{条件}操作数1,操作数2
TEQ指令用于把一个寄存器的内容和另一个寄存器的内容或立即数进行按位的异或运算,并根据运算结果更新CPSR中条件标志位的值。
该指令通常用于比较操作数1和操作数2是否相等。
指令示例:
TEQR1,R2;将寄存器R1的值与寄存器R2的值按位异或,并根据结果设置CPSR的标志位
7、ADD指令
ADD指令的格式为:
ADD{条件}{S}目的寄存器,操作数1,操作数2
ADD指令用于把两个操作数相加,并将结果存放到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
指令示例:
ADDR0,R1,R2;R0=R1+R2
ADDR0,R1,#256;R0=R1+256
ADDR0,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:
ADDSR0,R4,R8;加低端的字
ADCSR1,R5,R9;加第二个字,带进位
ADCSR2,R6,R10;加第三个字,带进位
ADCR3,R7,R11;加第四个字,带进位
9、SUB指令
SUB指令的格式为:
SUB{条件}{S}目的寄存器,操作数1,操作数2
SUB指令用于把操作数1减去操作数2,并将结果存放到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
该指令可用于有符号数或无符号数的减法运算。
指令示例:
SUBR0,R1,R2;R0=R1-R2
SUBR0,R1,#256;R0=R1-256
SUBR0,R2,R3,LSL#1;R0=R2-(R3<<1)
10、SBC指令
SBC指令的格式为:
SBC{条件}{S}目的寄存器,操作数1,操作数2
SBC指令用于把操作数1减去操作数2,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
该指令使用进位标志来表示借位,这样就可以做大于32位的减法,注意不要忘记设置S后缀来更改进位标志。
该指令可用于有符号数或无符号数的减法运算。
指令示例:
SUBSR0,R1,R2;R0=R1-R2-!
C,并根据结果设置CPSR的进位标志位
11、RSB指令
RSB指令的格式为:
RSB{条件}{S}目的寄存器,操作数1,操作数2
RSB指令称为逆向减法指令,用于把操作数2减去操作数1,并将结果存放到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
该指令可用于有符号数或无符号数的减法运算。
指令示例:
RSBR0,R1,R2;R0=R2–R1
RSBR0,R1,#256;R0=256–R1
RSBR0,R2,R3,LSL#1;R0=(R3<<1)-R2
12、RSC指令
RSC指令的格式为:
RSC{条件}{S}目的寄存器,操作数1,操作数2
RSC指令用于把操作数2减去操作数1,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
该指令使用进位标志来表示借位,这样就可以做大于32位的减法,注意不要忘记设置S后缀来更改进位标志。
该指令可用于有符号数或无符号数的减法运算。
指令示例:
RSCR0,R1,R2;R0=R2–R1-!
C
13、AND指令
AND指令的格式为:
AND{条件}{S}目的寄存器,操作数1,操作数2
AND指令用于在两个操作数上进行逻辑与运算,并把结果放置到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
该指令常用于屏蔽操作数1的某些位。
指令示例:
ANDR0,R0,#3;该指令保持R0的0、1位,其余位清零。
14、ORR指令
ORR指令的格式为:
ORR{条件}{S}目的寄存器,操作数1,操作数2
ORR指令用于在两个操作数上进行逻辑或运算,并把结果放置到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
该指令常用于设置操作数1的某些位。
指令示例:
ORRR0,R0,#3;该指令设置R0的0、1位,其余位保持不变。
15、EOR指令
EOR指令的格式为:
EOR{条件}{S}目的寄存器,操作数1,操作数2
EOR指令用于在两个操作数上进行逻辑异或运算,并把结果放置到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
该指令常用于反转操作数1的某些位。
指令示例:
EORR0,R0,#3;该指令反转R0的0、1位,其余位保持不变。
16、BIC指令
BIC指令的格式为:
BIC{条件}{S}目的寄存器,操作数1,操作数2
BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中。
操作数1应是一个寄存器,操作数2可以是一个寄存器,被移位的寄存器,或一个立即数。
操作数2为32位的掩码,如果在掩码中设置了某一位,则清除这一位。
未设置的掩码位保持不变。
指令示例:
BICR0,R0,#%1011;该指令清除R0中的位0、1、和3,其余的位保持不变。
3.3.3乘法指令与乘加指令
ARM微处理器支持的乘法指令与乘加指令共有6条,可分为运算结果为32位和运算结果为64位两类,与前面的数据处理指令不同,指令中的所有操作数、目的寄存器必须为通用寄存器,不能对操作数使用立即数或被移位的寄存器,同时,目的寄存器和操作数1必须是不同的寄存器。
乘法指令与乘加指令共有以下6条:
—MUL32位乘法指令
—MLA32位乘加指令
—SMULL64位有符号数乘法指令
—SMLAL64位有符号数乘加指令
—UMULL64位无符号数乘法指令
—UMLAL64位无符号数乘加指令
1、MUL指令
MUL指令的格式为:
MUL{条件}{S}目的寄存器,操作数1,操作数2
MUL指令完成将操作数1与操作数2的乘法运算,并把结果放置到目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。
其中,操作数1和操作数2均为32位的有符号数或无符号数。
指令示例:
MULR0,R1,R2;R0=R1×R2
MULSR0,R1,R2;R0=R1×R2,同时设置CPSR中的相关条件标志位
2、MLA指令
MLA指令的格式为:
MLA{条件}{S}目的寄存器,操作数1,操作数2,操作数3
MLA指令完成将操作数1与操作数2的乘法运算,再将乘积加上操作数3,并把结果放置到目的寄存器中,同时可以根据运算结果设置CPSR中相应的条件标志位。
其中,操作数1和操作数2均为32位的有符号数或无符号数。
指令示例:
MLAR0,R1,R
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第3章 ARM微处理器的指令系统 ARM 微处理器 指令系统