1、3.3 ARM指令集及应用程序设计 3.3.1 ARM指令集概述,1. ARM指令分类 ARM指令集总体分为6类指令 数据处理指令:完成寄存器中数据的算术和逻辑运算操作。 程序状态寄存器处理指令 跳转指令 Load/Store指令:唯一用于寄存器和存储器之间进行数据传送的指令。 异常中断产生指令 协处理器指令,所有指令都是32bit。 大多数指令都在单周期内完成。 绝大多数指令都可以条件执行。 load/store体系结构。 指令集可以通过协处理器扩展,2. ARM指令的特点,3. 指令格式,ARM指令的基本格式如下: S ,其中: opcode 指令助记符,如LDR、STR等。 cond 执
2、行条件,如EQ、NE等。 S 是否影响CPSR寄存器的值 Rd 目标寄存器。 Rn 第1操作寄存器。 operand2 第2个操作数。,在上面的基本格式中,“”符号内的项是必需的,“”符号内的项是可选的。 例如,是指令助记符,这是必须书写的;而为指令执行条件,是可选项。若不书写,则使用默认条件AL(无条件执行)。一条典型的ARM指令编码格式为:,指令举例如下: LDR R0,R1 ;读取R1地址上的存储器单元内容,执行条件AL BEQ D1 ;分支指令,执行条件EQ,即相等则跳转到D1 ADDS R1,R1,#1 ;加法指令,R1+1 R1,影响CPSR寄存器(S) SUBNES R1,R1,
3、#0x10 ;条件执行减法运算(NE),R1-0x10=R1,影响CPSR寄存器(S),在ARM指令中,灵活地使用第2操作数能够提高代码效率。第2个操作数的形式如下:(1) Rm在寄存器方式下,操作数即为寄存器的数值。寄存器方式应用举例: SUB R1,R1,R2 ;R1-R2R1,(2) #inmed_8r常数表达式 该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到的。 合法常量:0x3FC、0、0xF0000000、200、0xF0000001。 非法常量:0xlFE、511、0xFFFF、0x1010、0xF0000010。 常数表达式应用举例:MOV R0,#1 ;R
4、01AND R1,R2,#0x0F ;R2与0x0F,结果保存在R1,(3) Rm,shift寄存器移位方式 将寄存器的移位结果作为操作数,但Rm值保持不变,移位方法如下:立即数控制寄存器移位,例如: MOV R0,R1,LSL #2 寄存器控制寄存器移位,例如: MOV R0,R1,LSR R5,大多数指令都可以选用条件后缀进行条件测试,使用指令条件后缀可实现高效的逻辑操作。条件后缀只是影响指令是否执行,不影响指令的功能。表3-5所列为指令条件码表。,4.条件后缀,3.3.2. ARM数据处理指令,ARM的数据处理指令主要完成寄存器中数据的算术和逻辑运算操作。 ARM数据处理指令大致可分为6
5、类: 算术运算指令: ADD ADC SUB SBC RSBRSC 逻辑运算指令: AND ORR EOR BIC 数据传送指令: MOV MVN 比较指令: CMP CMN 测试指令: TST TEQ 乘法指令: MUL MLA UMULL UMLALSMULL SMLAL上述指令只能对寄存器操作,不能针对存储器,所有的操作数要么来自寄存器,要么来自立即数,不会来自存储器。 如果有结果,则结果一定是为32位宽,并且放在一个寄存器中,不会写入存储器。 每一个操作数寄存器和结果寄存器都在指令中独立指出,即:ARM指令采用3地址模式:Rd, Rn, Rm 所有ARM数据处理指令均可选择使用S后缀,
6、以影响状态标志。 比较指令CMP、CMN、TST和TEQ不需要后缀S,它们会直接影响状态标志。,ARM数据处理指令的特点,(1) 数据传送指令 MOV数据传送指令,MOV指令将8位图立即数或寄存器(operand2)传送到目标寄存器(Rd),可用于移位运算等操作。指令格式如下: MOVcondS Rd,operand2 指令举例如下: MOVS R3,R1,LSL #2;R3R12,并影响标志位 MOV PC,LR ;PC = LR,子程序返回, MVN数据非传送指令,MVN指令将8位图立即数或寄存器(operand2)按位取反后传送到目标寄存器(Rd)。因为其具有取反功能,所以可以加载范围更
7、广的立即数。 指令格式如下: MVNcondS Rd,operand2 指令举例如下: MVN R1,#0xFF ;R10xFFFFFF00 MVN R1,R2 ;将R2取反,结果存到Rl,(2) 算术逻辑运算指令 ADD加法运算指令,ADD指令将operand2的数据与Rn的值相加,结果保存到Rd寄存器. 指令格式如下: ADDcondS Rd,Rn,operand2 指令举例如下: ADDS R1,R1,#1 ;R1R1+1 ADDS R3,R1,R2,LSL #2 ;R3R1+R22, SUB减法运算指令,SUB指令用寄存器Rn减去operand2,结果保存到Rd中。 指令格式如下: S
8、UBcondS Rd,Rn,operand2指令举例如下: SUBS R0,R0,#l ;R0R0-1 SUB R6,R7,R5 ;R6R7-R5, RSB逆向减法指令,RSB指令用寄存器operand2减去Rn,结果保存到Rd中。指令格式如下: RSBcondS Rd,Rn,operand2指令举例如下: RSB R3,R1,#0xFF00 ;R30xFF00-R1 RSBS R1,R2,R2,LSL #2;R1R22- R2R23, ADC带进位加法指令,ADC指令将operand2的数据与Rn的值相加,再加上CPSR中的C条件标志位,结果保存到Rd寄存器。 指令格式如下: ADCcond
9、S Rd,Rn,operand2指令举例如下: ADDS R0,R0,R2 ; 使用ADC实现64位加法, ADC R1,R1,R3 ;(R1、R0)(R1、R0)+(R3、R2), SBC带进位减法指令,SBC指令用寄存器Rn减去operand2,再减去CPSR中的C条件标志位的“非”(即若C标志清零,则结果减去1),结果保存到Rd中。指令格式如下: SBCcondS Rd,Rn,operand2指令举例如下: SUBS R0,R0,R2 ;使用SBC实现64位减法, SBC R1,R1,R3 ;(R1、R0)(R1、R0)-(R3、R2), RSC带进位逆向减法指令,RSC 指令用寄存器o
10、perand2减去Rn,再减去CPSR中的C条件标志位,结果保存到Rd中。指令格式如下: RSCcondS Rd,Rn,operand2指令举例如下: RSBS R2,R0,#0 RSC R3,R1,#0 ;使用RSC指令实现求64位数值的负数, AND逻辑“与”操作指令,AND指令将operand2的值与寄存器Rn的值按位逻辑“与”操作,结果保存到Rd中。指令格式如下: ANDcondS Rd,Rn,operand2指令举例如下: ANDS R0,R0,#0x01 ;R0R0&0x01,取出最低位数据 AND R2,R1,R3 ;R2R1&R3, ORR逻辑“或”操作指令,ORR指令将ope
11、rand2的值与寄存器Rn的值按位逻辑“或”操作,结果保存到Rd中。指令格式如下: ORRcondS Rd,Rn,operand2 指令举例如下: ORR R0,R0,#0x0F ;将R0的低4位置1,EOR逻辑“异或”操作指令,EOR指令将operand2的值与寄存器Rn的值按位逻辑“异或”操作,结果保存到Rd中。指令格式如下: EORcondS Rd,Rn,operand2指令举例如下: EOR R1,R1,#0x0F ;将Rl的低4位取反 EORS R0,R5,#0x01 ;将R0=R50x01,并影响标志位, BIC位清除指令,BIC指令将寄存器Rn的值与operand2的值的反码按位
12、逻辑“与”操作,结果保存到Rd中。指令格式如下: BICcondS Rd,Rn,operand2指令举例如下: BIC R1,R1,#0x0F ;将R1的低4位清零,其它位不变,(3) 比较指令 CMP比较指令,CMP指令将寄存器Rn的值减去operand2的值,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。 指令格式如下: CMPcond Rn,operand2 指令举例如下: CMP R1,#10 ;R1与10比较,设置相关标志位,CMN负数比较指令,CMN指令将寄存器Rn的值加上operand2的值,根据操作的结果更新CPSR中的相应条件标
13、志位,以便后面的指令根据相应的条件标志来判断是否执行。 指令格式如下: CMNcond Rn,operand2 指令举例如下: CMN R0,#1 ;R0+1,判断R0是否为1的补码。若是,则Z位置1。 CMN指令与ADDS指令的区别在于CMN指令不保存运算结果。CMN指令可用于负数比较,比如“CMN R0,#1”指令则表示R0与-1比较。若R0为-1(即1的补码),则Z置位;否则Z复位, TST位测试指令,TST指令将寄存器Rn的值与operand2的值按位逻辑“与”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。 指令格式如下: TSTc
14、ond Rn,operand2 指令举例如下: TST R0,#0x01 ;判断R0的最低位是否为0 TST Rl,#0x0F ;判断R1的低4位是否为0 TST指令与ANDS指令的区别在于TST指令不保存运算结果。TST指令通常与EQ、NE条件码配合使用。当所有测试位均为0时,EQ有效。而只要有一个测试位不为0,则NE有效。, TEQ相等测试指令,TEQ指令将寄存器Rn的值与operand2的值按位逻辑“异或”操作,根据操作的结果更新CPSR中的相应条件标志位,以便后面的指令根据相应的条件标志来判断是否执行。 指令格式如下: TEQcond Rn,operand2 指令举例如下: TEQ R
15、0,R1 ;比较R0与R1是否相等(不影响V位和C位) TEQ指令与EORS指令的区别在于TEQ指令不保存运算结果。使用TEQ进行相等测试时,常与EQ、NE条件码配合使用。当两个数据相等时,EQ有效;否则NE有效。,(4). 乘法指令,ARM7TDMI(-S)具有3232乘法指令、3232乘加指令,3232结果为64位的乘乘加指令。ARM乘法指令如表3-9所列,MUL32位乘法指令,MUL指令将Rm和Rs中的值相乘,结果的低32位保存到Rd中。指令格式如下: MULcondS Rd,Rm,Rs指令举例如下: MUL R1,R2,R3;R1=R2R3 MULS R0,R3,R7 ;R0=R3R7
16、,同时设置CPSR中的N位和Z位,MLA32位乘加指令,MLA指令将Rm和Rs中的值相乘,再将乘积加上第3个操作数,结果的低32位保存到Rd中。指令格式如下: MLAcondS Rd,Rm,Rs,Rn指令举例如下: MLA R1,R2,R3,R0 ;R1=R2R3+R0,UMULL64位无符号乘法指令,UMULL指令将Rm和Rs中的值作无符号数相乘,结果的低32位保存到RdLo中,而高32位保存到RdHi中。指令格式如下:UMULLcondS RdLo,RdHi,Rm,Rs指令举例如下:UMULL R0,R1,R5,R8 ;(R1、R0)R5R8,UMLAL64位无符号乘加指令,UMLAL指令
17、将Rm和Rs中的值作无符号数相乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,而高32位保存到RdHi中。指令格式如下: UMLALcondS RdLo,RdHi,Rm,Rs指令举例如下: UMLAL R0,R1,R5,R8 ;(R1、R0)R5R8+(R1、R0),SMULL64位有符号乘法指令,SMULL指令将Rm和Rs中的值作有符号数相乘,结果的低32位保存到RdLo中,而高32位保存到RdHi中。指令格式如下: SMULLcondS RdLo,RdHi,Rm,Rs指令举例如下: SMULL R2,R3,R7,R6 ;(R3、R2)R7R6,SMLAL64位有符号乘加指令,SMLAL指令将Rm和Rs中的值作有符号数相乘,64位乘积与RdHi、RdLo相加,结果的低32位保存到RdLo中,而高32位保存到RdHi中。指令格式如下: SMLALcondS RdLo,RdHi,Rm,Rs指令举例如下: SMLAL R2,R3,R7,R6 ; (R3、R2)R7R6+(R3、R2),指令条件码表,返回,ARM数据处理指令表,返回,ARM乘法指令,返回,