1第三章ARM指令集3.1ARM指令集概述3.2ARM寻址方式3.3ARM指令详细介绍2ARM指令集与x86指令集的主要不同点ARM指令集规整指令格式Ø即:正交指令格式三地址指令由指令的附加位决定运算完毕后是否改变状态标志状态标志位只有4位有两种指令密度无整数除法指令大多数ARM指令都可以条件执行有适合DSP处理的乘加指令Load/Store访存体系结构x86指令集非规整指令格式Ø即:非正交指令格式二地址指令指令隐含决定运算完毕后是否改变状态标志状态标志位有6位单一指令密度有整数除法指令专用条件判断指令进行程序分支没有适合DSP处理的乘加指令运算指令能够访问存储器33.1.1ARM指令集编码ARM指令集是以32位二进制编码的方式给出的,大部分的指令编码中定义了第一操作数、第二操作数、目的操作数、条件标志影响位以及每条指令所对应的不同功能实现的二进制位。每条32位ARM指令都具有不同的二进制编码方式,和不同的指令功能相对应。Shifter_operandRdRnsopcode001cond31282725242120191615121187043.1.2条件执行不等于(Notequal)无符号的大于或等于无符号的小于负数(Minus)等于(Equal)溢出(Overflow)没溢出无符号的大于无符号的小于或大于正数或零小于(LessThan)大于(GreaterThan)小于等于总是执行(Always)大于等于EQNECS/HSCC/LOPLVSHILSGELTGTLEALMIVCSuffix描述Z=0C=1C=0Z=1测试的标志位N=1N=0V=1V=0C=1&Z=0C=0orZ=1N=VN!=VZ=0&N=VZ=1orN=!V5ARM指令的助记符ARM指令在汇编程序中用助记符表示,一般ARM指令的助记符格式为:opcode{cond}{S}Rd,Rn,op2其中:opcode操作码,如ADD表示算术加操作指令;{cond}决定指令执行的条件域;{S}决定指令执行是否影响CPSR寄存器的值;Rd目的寄存器;Rn第一个操作数,为寄存器;op2第二个操作数。6没有上溢出V=0VC上溢出V=1VS正数或零N=0PL负数(minus)N=1MI无符号数小于C=0CC/LO无符号数大于或等于C=1CS/HS不相等Z=0NE相等Z=1EQ含义标志条件码助记符ARM指令根据CPSR中的条件位自动判断是否执行指令,在条件满足时,指令执行,否则指令被忽略。在ARM的指令编码表中,统一占用编码的最高四位[31:28]来表示“条件码”(即“cond”)。7无条件执行(指令默认条件)任何AL该指令从不执行ARMv3之前NV有符号数小于或等于Z=1,N!=VLE有符号数大于Z=0,N=VGT有符号数小于N!=VLT有符号数大于或等于N=VGE无符号数小于或等于C=0,Z=lLS无符号数大于C=1,Z=0HI含义标志条件码助记符8ARM指令可以通过添加适当的条件码后缀来达到条件执行的目的。这样可以提高代码密度,减少分支跳转指令数目,提高性能。CMPr3,#0BEQskipADDr0,r1,r2skip默认情况下,数据处理指令不影响条件码标志位,但可以选择通过添加“S”来影响标志位。CMP不需要增加“S”就可改变相应的标志位。loop…SUBSr1,r1,#1BNEloop如果Z标志清零则跳转R1减1,并设置标志位93.2ARM寻址方式寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式。ARM处理器具有8种基本寻址方式,以下列出:-寄存器寻址-立即寻址-寄存器偏移寻址-寄存器间接寻址-基址寻址-块拷贝寻址-堆栈寻址-相对寻址10立即数寻址操作数本身直接在指令中给出,取出指令也就获得了操作数,这个操作数也称为立即数。例:ADDR0,R1,#5;R0=R1+5MOVR0,#0x55;R0=0x55其中:操作数5,0x55就是立即数,立即数在指令中要以“#”为前缀,后面跟实际数值。11寄存器寻址寄存器的值即为操作数。ARM指令普遍采用此种寻址方式。例:ADDR0,R1,R2;R0=R1+R2MOVR0,R1;R0=R112寄存器偏移寻址寄存器偏移寻址是ARM指令集特有的寻址方式。当第2作数是寄存器偏移方式时,第2个寄存器操作数在与第1操作数结合之前,选择进行移位操作。寄存器偏移寻址指令举例如下:MOVR0,R2,LSL#3;R2的值左移3位,结果放入R0,即R0=R2×8ANDSR1,R1,R2,LSLR3;R2的值左移R3位,然后与R1相“与”;结果放入R1,并且影响标志位。SUBR11,R12,R3,ASR#5;R12-R3÷32,然后存入R11。13寄存器偏移寻址(续)可采用的移位操作如下:LSL:逻辑左移(LogicalShiftLeft),低端空出位补0。LSR:逻辑右移(LogicalShiftRight),高端空出位补0。ASR:算术右移(ArithmeticShiftRight),移位过程中保持符号位不变,即若源操作数为正数,则字的高端空出的位补0;否则补1。ROR:循环右移(RotateRight),由字低端移出的位填入字高端空出的位。RRX:带扩展的循环右移(RotateRightextendedbylplace),操作数右移1位,高端空出的位用原C标志值填充。如果指定后缀“S”,则将Rm原值的位[0]移到进位标志。14移位操作示意图各种移位操作如下图所示:(c)ASR移位操作(d)ROR移位操作00(e)RRX移位操作C(a)LSL移位操作(b)LSR移位操作15寄存器寻址第二操作数的移位位数移位位数可以用立即数方式或者寄存器方式给出,如下所示:ADDR3,R2,R1,LSR#2;R3—R2+R1÷4ADDR3,R2,R1,LSRR4;R3—R2+R1÷2R4寄存器R1的内容分别逻辑右移2位、R4位(亦即R1÷4、R1÷2R4),再与寄存器R2的内容相加,结果放入R3中。16寄存器间接寻址寄存器中的值为操作数的物理地址,而实际的操作数存放在存储器中。例:LDRR1,[R2]将R2指向的存储单元的数据读出,保存在R1中。SWPR1,R1,[R2]将寄存器R1的值与R2指定的存储单元的内容交换17基址加偏址寻址前变址模式:LDRR0,[R1,#4];R0←[R1+4]自动变址模式:LDRR0,[R1,#4]!;R0←[R1+4]、R1←R1+4后变址模式:LDRR0,[R1],#4;R0←[R1]、R1←R1+4将寄存器(称为基址寄存器)的值与指令中给出的偏移地址量相加,所得结果作为操作数的物理地址。例:18基址加偏址寻址基址寄存器的地址偏移可以是一个立即数,也可以是另一个寄存器,并且在加到基址寄存器前还可以经过移位操作,如下所示:LDRr0,[r1,r2];r0—mem32[r1+r2]LDRr0,[r1,r2,LSL#2];r0—[r1+r2*4]19堆栈寻址堆栈寻址用于数据栈与寄存器组之间批量数据传输。当数据写入和读出内存的顺序不同时,使用堆栈寻址可以很好的解决这问题。例:STMFDR13!,{R0,R1,R2,R3,R4};LDMFDR13!,{R0,R1,R2,R3,R4}20堆栈寻址存储器堆栈可分为两种:向上生长:向高地址方向生长,称为递增堆栈。向下生长:向低地址方向生长,称为递减堆栈。满堆栈堆栈指针指向最后压入的堆栈的有效数据项空堆栈堆栈指针指向下一个待压入数据的空位置21堆栈寻址(续1)有4种类型的堆栈组合满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址。指令如LDMFA、STMFA等。空递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置。指令如LDMEA、STMEA等。满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFD、STMFD等。空递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置。指令如LDMED、STMED等。22块拷贝寻址F块拷贝寻址是多寄存器传送指令LDM/STM的寻址方式。LDM/STM指令可以把存储器中的一个数据块加载到多个寄存器中,也可以把多个寄存器中的内容保存到存储器中。寻址操作中的寄存器可以是R0-R15这16个寄存器的子集或是所有寄存器。LDMIAR0,{R1-R5};STMIAR1,{R1-R5};23多寄存器传送指令映射表STM=将寄存器内容存入内存单元(堆栈操作:入栈)LDM=将内存单元内容存入寄存器(堆栈操作:出栈)指针满指针满指针空指针空LDMIBLDMEDSTMIBSTMFASTMIASTMEALDMIALDMFDLDMDBLDMEASTMDBSTMFDSTMDASTMEDLDMDALDMFA地址增加在传送之后地址增加在传送之前地址减小在传送之前地址减小在传送之后24数据块传送:I=向地址增大方向处理数据传送(Increment)D=向地址减小方向处理数据传送(Decrement)A=先传送数据后改变地址(after)B=先改变地址后传送数据(before)堆栈操作:F=满栈顶指针(full)E=空栈顶指针(empty)A=堆栈向高地址方向增长(ascendingstack)D=堆栈向低地址方向增长(decendingstack)25相对寻址是基址寻址的一种变通。由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。相对寻址指令举例如下:BLSUBR1;保存子程序返回地址;调用到SUBR1子程序BEQLOOP;条件跳转到LOOP标号处…LOOPMOVR6,#1…SUBR1…相对寻址