嵌入式系统概论第七章_第1页
嵌入式系统概论第七章_第2页
嵌入式系统概论第七章_第3页
嵌入式系统概论第七章_第4页
嵌入式系统概论第七章_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章ARM指令集

ARM指令集结构(ISA)发展到今天,已经形成一个比较庞大的家族,有多个功能各异的版本。由于ARMv1、ARMv2和ARMv3已经淘汰,而ARMv4T又是后续几个版本的基础,因此本章主要介绍ARMv4T指令系统。ARMv4T共49条指令,分为6类,即分支指令、数据处理指令、程序状态寄存器传送指令、Load/Store指令、协处理器指令和异常产生指令。本章按指令系统的基本分类方法,分三大部分(即运算、传送和控制)分别介绍各条指令的基本功能和使用方法。

目录7.1条件执行7.2操作数预处理7.3运算类指令7.4控制类指令7.5传送类指令7.6Thumb指令集概述习题

7.1条件执行所有的ARM指令都可以条件执行,也就是根据CPSR寄存器中N、Z、C、V等标志位决定是否执行该指令。

条件码(cond)条件码助记符含义CPSR中条件标志位值0000EQ相等Z=10001NE不相等Z=00010CS/HS无符号数大于/等于C=10011CC/LO无符号数小于C=00100MI负数N=10101PL非负数N=00110VS上溢出V=10111VC没有上溢出V=01000HI无符号数大于(higher)C=1且Z=01001LS无符号数小于/等于C=0或Z=11010GE带符号数大于/等于N=1且V=1或N=0且V=01011LT带符号数小于N=1且V=0或N=0且V=11100GT带符号数大于Z=0且N=V1101LE带符号数小于/等于Z=1或N!=V1110AL无条件执行1111NV未定义7.1条件执行例如求最大公约数的不采用条件执行的ARM汇编代码为:gcd CMP R1,R2 BEQ complete BLT lessthan SUB R1,R1,R2 B gcdlessthan SUB R2,R2,R1 B gcdcomplete而采用条件执行的ARM汇编代码为:gcd CMP R1,R2 SUBGT R1,R1,R2 SUBLT R2,R2,R1 BNE gcd7.2操作数预处理

ARM处理器一个显著的特征就是在操作数进入ALU之前,先对其中一个操作数进行指定位数的左移或右移处理。这种功能增强了许多数据处理操作的灵活性。

1.立即数的预处理在运算类指令中,ARM允许立即数寻址,立即数位于指令格式中第0~11位。ARM利用预处理功能,使得在指令格式中留给立即数只有12位的情况下,能够生成一个32位的立即数Imm_32。具体方法是把指令格式中第0~11位再分成两部分,其中第0~7位用来存放一个8位的立即数Imm_8,第8~11位存放一个4位的数值rotate_imm。真正的立即数Imm_32通过把Imm_8循环右移rotate_imm×2次来生成。由于rotate_imm只有4位,最大表示值为15,不能把Imm_8移位成32位,因此,ARM规定循环右移次数为rotate_imm×2。7.2操作数预处理例如指令:MOVR8,#0x04000000在ADS1.2中对应的机器码为:0xE3A08640其中第0~11位为0x640,当把0x40(Imm_8)看成高位为0的32位数,将其循环右移0x6(rotate_imm)×2次后,结果为0x04000000。即立即数0x04000000的指令编码为0x640。用户不需要计算某个立即数的12位机器编码是多少,这由ARM汇编编译器来做。也就是说,汇编指令中的立即数Imm_32由汇编编译器将其分解成能通过上述方法生成Imm_32的Imm_8(8位)和rotate_imm(4位)。

7.2操作数预处理2.寄存器数的预处理

在运算类指令和传送类指令中,ARM允许对某个寄存器的值在运算之前进行预处理,即做某种类型的移位操作。ARM共规定了5种类型的移位操作,它们分别是算术右移(ASR)、逻辑右移(LSR)、逻辑左移(LSL)、循环右移(ROR)和扩展循环右移(RRX)。

0逻辑左移(LSL):0逻辑右移LSR):算术右移(ASR):循环右移(ROR):扩展循环右移(RRX):C7.2操作数预处理移位的次数可以由立即数或另一个寄存器给出。由于扩展循环右移(RRX)只移动1位,因此,寄存器数的预处理有9种情况,它们对应的汇编格式如下。<Rm>,LSL#<shift_imm><Rm>,LSL<Rs><Rm>,LSR#<shift_imm><Rm>,LSR<Rs><Rm>,ASR#<shift_imm><Rm>,ASR<Rs><Rm>,ROR#<shift_imm><Rm>,ROR<Rs><Rm>,RRX其中,Rm是需要进行移位操作的寄存器;#<shift_imm>是需要移位的位数,在ARM指令格式中所占的位数为5位;Rs是包含移位位数的寄存器。7.2操作数预处理(1)<Rm>,LSL#<shift_imm>指令的操作数shifter_operand为寄存器Rm的数值逻辑左移shift_imm位。这里shift_imm的范围为0~31。如果shift_imm为0,则shifter_operand的值就是Rm的值,循环器的进位值(Carry-out)为CPSR中的C标志位;如果shift_imm不为零,则shifter_operand的值为Rm中值逻辑左移shift_imm位后的值,循环器的进位值为Rm寄存器中最后被移出的位Rm[32-shift_imm]的值。举例如下:MOVR3,#30MOVR4,R3,LSL#0x12则寄存器R4的值为30×218=7864320=0x00780000。

7.2操作数预处理(2)<Rm>,LSL<Rs>指令的操作数shifter_operand为寄存器Rm的数值逻辑左移一定位数的值,移位的位数由Rs寄存器的最低8位Rs[7:0]决定。当Rs[7:0]=0时,shifter_operand的值就是Rm的值,循环器的进位值(Carry-out)为CPSR中的C标志位;当0<Rs[7:0]<32时,shifter_operand的值为Rm中值逻辑左移Rs[7:0]位后的值,循环器的进位值为Rm寄存器中最后被移出的位Rm[32-Rs[7:0]]的值;当Rs[7:0]=32时,shifter_operand的值为0,循环器的进位值为Rm[0];当Rs[7:0]>32时,shifter_operand的值为0,循环器的进位值为0。举例如下:MOVR3,#0xF000000EMOVR4,R3,LSLR3则寄存器R4的值为0x00038000,即将#0xF000000E逻辑左移14位。

7.2操作数预处理(3)<Rm>,LSR#<shift_imm>指令的操作数shifter_operand为寄存器Rm的数值逻辑右移#<shift_imm>位。这里shift_imm的范围为1~32,当shift_imm=32时在指令中被编码为0。进行移位操作后,空出的位置0。当shift_imm=32时,操作数shifter_operand的值为0,循环器的进位值为Rm的最高位Rm[31];其他情况下,操作数shifter_operand的值为寄存器Rm的数值逻辑右移shift_imm位,循环器的进位值为Rm最后被移出位的值。举例如下:MOVR3,#0xF000000EMOVR4,R3,LSR#32则R4的值为0。若执行MOVR3,#0x30MOVR4,R3,LSR#0x5则R4的值为1。

7.2操作数预处理(4)<Rm>,LSR<Rs>指令的操作数shifter_operand为寄存器Rm的数值逻辑右移一定位数的值,移位的位数由Rs寄存器的最低8位Rs[7:0]决定。当Rs[7:0]=0时,shifter_operand的值就是Rm的值,循环器的进位值(Carry-out)为CPSR中的C标志位;当0<Rs[7:0]<32时,shifter_operand的值为Rm中值逻辑右移Rs[7:0]位后的值,循环器的进位值为Rm寄存器中最后被移出的位Rm[Rs[7:0]-1]的值;当Rs[7:0]=32时,shifter_operand的值为0,循环器的进位值为Rm[31];当Rs[7:0]>32时,shifter_operand的值为0,循环器的进位值为0。举例如下:MOVR3,#0xF000000EMOVR4,R3,LSRR3则寄存器R4的值为0x0003C000,即将#0xF000000E逻辑右移14位。7.2操作数预处理(5)<Rm>,ASR#<shift_imm>指令的操作数shifter_operand为寄存器Rm的数值算术右移#<shift_imm>位。这里shift_imm的范围为1~32,当shift_imm=32时在指令中被编码为0。进行移位操作后,空出的位置Rm的最高位值Rm[31]。当shift_imm=32时,将进行32次算术右移操作,这时若Rm[31]=0,则操作数shifter_operand的值为0,循环器的进位值为Rm的最高位Rm[31],也为0;若Rm[31]=1,则操作数shifter_operand的值为0xFFFFFFFF,循环器的进位值为Rm的最高位Rm[31],也为1。其他情况下,操作数shifter_operand的值为寄存器Rm的数值算术右移shift_imm位,循环器的进位值为Rm最后被移出位的值。举例如下:MOVR3,#0xF000000EMOVR4,R3,ASR#32则R4的值为0xFFFFFFFF。若执行MOVR3,#0x30MOVR4,R3,ASR#32则R4的值为0。7.2操作数预处理(6)<Rm>,ASR<Rs>指令的操作数shifter_operand为寄存器Rm的数值算术右移一定位数的值,移位的位数由Rs寄存器的最低8位Rs[7:0]决定。当Rs[7:0]=0时,shifter_operand的值就是Rm的值,循环器的进位值(Carry-out)为CPSR中的C标志位;当0<Rs[7:0]<32时,shifter_operand的值为Rm中值算术右移Rs[7:0]位后的值,循环器的进位值为Rm寄存器中最后被移出的位Rm[Rs[7:0]-1]的值;当Rs[7:0]≥32时,将进行32次算术右移操作,这时若Rm[31]=0,则shifter_operand的值为0,循环器的进位值为Rm的最高位Rm[31],也就是为0;若Rm[31]=1,则shifter_operand的值为0xFFFFFFFF,循环器的进位值为Rm的最高位Rm[31],也就是为1。举例如下:MOVR3,#0xF000000EMOVR4,R3,ASRR3则寄存器R4的值为0xFFFFC000,即将#0xF000000E算术右移14位。

7.2操作数预处理(7)<Rm>,ROR#<shift_imm>指令的操作数shifter_operand为寄存器Rm的数值循环右移#<shift_imm>位。这里shift_imm的范围为1~31。进行移位操作后,从寄存器右端移出的位又插入到寄存器左端空出的位。则操作数shifter_operand的值为寄存器Rm的数值循环右移shift_imm位,循环器的进位值为Rm最后被移出位的值。举例如下:MOVR3,#0x00000FF0MOVR4,R3,ROR#10则寄存器R4的值为0xFC000003。7.2操作数预处理(8)<Rm>,ROR<Rs>指令的操作数shifter_operand为寄存器Rm的数值循环右移一定位数的值,移位的位数由Rs寄存器的最低8位Rs[7:0]决定。当Rs[7:0]=0时,shifter_operand的值就是Rm的值,循环器的进位值(Carry-out)为CPSR中的C标志位;当Rs[4:0]=0时,shifter_operand的值为Rm的值,循环器的进位值为Rm[31];当Rs[4:0]>0时,shifter_operand的值为寄存器Rm的数值循环右移Rs[4:0]位,循环器的进位值为Rm最后被移出的位Rm[Rs[4:0]-1]。举例如下:MOVR3,#0x00000FF0MOVR4,R3,RORR3则寄存器R4的值为0x0FF00000。7.2操作数预处理(9)<Rm>,RRX指令的操作数shifter_operand为寄存器Rm的数值右移一位,并用CPSR中的C标志位填补空出的位,CPSR中的C位则用移出的位代替。举例如下:MOVR3,#0x00000FF0MOVR4,R3,RRX则寄存器R4的值为0x000007F8。

7.3运算类指令

ARM的运算类指令主要包括数据处理指令和乘法指令,ARMv4T共有16条数据处理指令和6条乘法指令,如下表所示。指令助记符指令功能指令助记符指令功能MOV数据传送指令MVN数据求反传送指令CMP比较指令CMN基于相反数的比较指令TST位测试指令TEQ相等测试指令ADD加法指令ADC带进位加法指令SUB减法指令SBC带借位减法指令RSB逆向减法指令RSC带借位逆向减法指令AND逻辑与操作指令ORR逻辑或操作指令EOR逻辑异或操作指令BIC位清除指令MUL32位乘法指令MLA32位带加数的乘法指令SMULL64位有符号数乘法指令SMLAL64位带加数有符号数乘法指令UMULL64位无符号数乘法指令UMLAL64位带加数无符号数乘法指令7.3运算类指令

1.MOV(传送指令)MOV指令将<shifter_operand>表示的数值传送到目标寄存器<Rd>中,并根据操作的结果有条件地更新CPSR中相应的标志位。指令的语法格式为:MOV{<cond>}{S}<Rd>,<shifter_operand>其中,<cond>为指令执行的条件码;<Rd>为目标寄存器;<shifter_operand>为向目标寄存器传送的数据,其寻址方式是立即数或寄存器。使用举例如下:将数据从一个寄存器传送到另一个寄存器中。MOVR4,R5;将一个立即数传送到一个寄存器中。MOVEQR4,#300

;若前一条指令的结果为0,则R4=3007.3运算类指令

2.MVN(相反数传送指令)MVN指令将<shifter_operand>表示的数值的反码传送到目标寄存器<Rd>中,并根据操作的结果有条件地更新CPSR中相应的标志位。指令的语法格式为:MVN{<cond>}{S}<Rd>,<shifter_operand>

其中各参数的用法与MOV指令相同。使用举例如下:如果需要给寄存器R4传送-300,则指令如下:MVNMIR4,#299

;若前一条指令的结果为负,则R4=-300

生成位掩码:MVNR4,#0x01

求一个数的反码:MVNR4,R47.3运算类指令

3.ADD(加法指令)ADD指令将<shifter_operand>表示的数值与寄存器<Rn>中的值相加,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:ADD{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,<cond>为指令执行的条件码,;<Rd>为目标寄存器;<Rn>为第一个源操作数所在的寄存器;<shifter_operand>为向目标寄存器传送的数据,其寻址方式是立即数或寄存器。使用举例如下:一个寄存器中值和一个立即数相加:ADDR4,R5,#300一个寄存器中值和另一个寄存器中中值经过预处理之后相加:ADDR4,R5,R6,LSL#37.3运算类指令

4.ADC(带进位加法指令)ADC指令将<shifter_operand>表示的数值与寄存器<Rn>中的值相加,再加上CPSR中C条件标志位的值,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:ADC{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,各参数用法同ADD指令。使用举例如下:ADC指令和ADD指令联合可以实现两个64位二进制数相加,比如要计算两个64位二进制数0x2345678912345678和0x4567890134567890的和,则对应的汇编程序代码如下。LDRR0,=0x12345678LDRR1,=0x23456789LDRR2,=0x34567890LDRR3,=0x45678901ADDSR4,R0,R2ADCR5,R1,R37.3运算类指令

5.SUB(减法指令)SUB指令从寄存器<Rn>中减去<shifter_operand>表示的数值,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:SUB{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,各参数用法同ADD指令。使用举例如下:一个寄存器中值减去一个立即数,并影响CPSR。SUBSR4,R5,#300下面代码段执行后,R8寄存器的值为0x11111111。LDRR0,=0xa0000000LDRR1,=0xb0000000LDRR2,=0x12345678LDRR3,=0x23456789ADDSR4,R0,R1SUBVSSR8,R3,R27.3运算类指令

6.SBC(带借位减法指令)SBC指令从<Rn>中减去<shifter_operand>表示的数值,再减去CPSR中C条件标志位的反码,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:SBC{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,各参数用法同ADD指令。SBC指令和SUB指令联合可以实现两个64位二进制数相减。如果寄存器R0和R1中存放一个64位二进制数,其中R0存放低32位,R1存放高32位。R2和R3中存放另一个64位二进制数,R2存放低32位,R3存放高32位。使用举例如下:下面的指令序列实现了两个64位二进制数的减法操作。

SUBSR4,R0,R2SBCR5,R1,R3

7.3运算类指令

7.RSB(逆向减法指令)RSB指令从<shifter_operand>表示的数值中减去寄存器<Rn>的值,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:RSB{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,<shifter_operand>为第1个源操作数;<Rn>为第2个源操作数;其他各参数用法同ADD指令。使用举例如下:求一个寄存器值的反码,并影响CPSR。RSBSR4,R5,#0

;R4=-R5求一个寄存器值的2n-1。RSBEQR4,R5,R5,LSL#n

;条件执行,R4=R5×(2n-1)7.3运算类指令

8.RSC(带借位逆向减法指令)RSC指令从<shifter_operand>表示的数值中减去寄存器<Rn>的值,再减去CPSR中C标志位的反码,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:RSC{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,各参数用法同RSB指令。使用举例如下:RSC指令的典型用法为求一个64位二进制数的负数。RSBSR2,R0,#0RSCR3,R1,#07.3运算类指令

9.AND(逻辑与指令)AND指令将<shifter_operand>表示的数值与寄存器<Rn>的值按位进行与运算,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:AND{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,<Rn>为第1个源操作数所在的寄存器;<shifter_operand>为第2个源操作数;其他各参数用法同MOV指令。AND指令可用于提取寄存器中某些位的值,具体做法是设置一个掩码值,将该值中对应于寄存器中欲提取的位设为1,其他的位设为0。将寄存器的值与该掩码做与操作,即可得想提取的位的值。使用举例如下:MOVR2,#0x80000000ANDR3,R3,R2

;提取R3寄存器的最高位

7.3运算类指令

10.ORR(逻辑或指令)ORR指令将<shifter_operand>表示的数值与寄存器<Rn>的值按位进行或运算,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:ORR{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,各参数用法同AND指令。使用举例如下:下面的汇编代码将R2寄存器中的高8位数据传送到R3的低8位中。MOVR0,R2,LSR#24

;将R2的高8位数据传送到R0中,R0的高24位设置为0ORRR3,R0,R3,LSL#8;将R3中数据逻辑左移8位,这时R3的低8位为0,ORR操作将R0(高24位为0)中低8位数据传送到寄存器R3中。7.3运算类指令

11.EOR(逻辑异或指令)EOR指令将<shifter_operand>表示的数值与寄存器<Rn>的值按位进行异或运算,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:EOR{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,各参数用法同AND指令。EOR指令可用于将寄存器中某些位的值取反。将某一位值与0做异或操作,该位值不变;将某一位值与1做异或操作,该位值将被求反。使用举例如下:下面的代码将R2中高16位值取反。LDRR1,=0xFFFF0000EORR3,R2,R17.3运算类指令

12.BIC(位清除指令)BIC指令将<shifter_operand>表示的数值与寄存器<Rn>的值的反码按位进行逻辑与运算,并把结果保存到目标寄存器<Rd>中,同时根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:BIC{<cond>}{S}<Rd>,<Rn>,<shifter_operand>其中,各参数用法同AND指令。BIC指令可用于将寄存器中某些位的值设置成0。将某一位值与1做BIC操作,该位值被设置成0;将某一位值与0做BIC操作,该位值保持不变。使用举例如下:下面的代码将R2中高16位值设置成0。LDRR1,=0xFFFF0000BICR3,R2,R17.3运算类指令

13.CMP(比较指令)CMP指令从寄存器<Rn>中减去<shifter_operand>表示的数值,根据操作的结果更新CPSR中相应的条件标志位,后面的指令就可以根据CPSR中相应的条件位来判断是否执行。指令的语法格式为:CMP{<cond>}<Rn>,<shifter_operand>其中,<cond>为指令执行的条件码,当<cond>忽略时指令为无条件执行;<Rn>为第1个操作数所在的寄存器;<shifter_operand>为第2个操作数,其寻址方式是立即数或寄存器。CMP指令类似于SUBS指令,只是CMP指令不保存结果,而SUBS指令需要保存结果,并且CMP指令总是影响CPSR中相应位。使用举例如下:CMPR2,R3

7.3运算类指令

14.CMN(基于相反数的比较指令)CMN指令将寄存器<Rn>中的值加上<shifter_operand>表示的数值,根据操作的结果更新CPSR中相应的条件标志位,后面的指令就可以根据CPSR中相应的条件位来判断是否执行。指令的语法格式为:CMN{<cond>}<Rn>,<shifter_operand>其中,各参数的使用方法与CMP指令相同。CMN指令通过给第1个操作数<Rn>加上第2个操作数<shifter_operand>的值来表示比较第1个操作数<Rn>和第2个操作数<shifter_operand>的负数。加上第2个操作数与减去第2个操作数的负数对CPSR中条件标志位的影响有细微的差别。当第2个操作数为0或者0x80000000时二者结果不同。使用举例如下:CMPR2,#0;C=1CMNR2,#0;C=07.3运算类指令

15.TST(位测试指令)TST指令将寄存器<Rn>中的值与<shifter_operand>表示的数值按位做逻辑与操作,根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:TST{<cond>}<Rn>,<shifter_operand>其中,各参数的使用方法与CMP指令相同。TST指令通常用于测试寄存器中某些(个)位是0还是1。使用举例如下:TSTR3,#01

;测试R3寄存器中最低位是0还是17.3运算类指令

16.TEQ(相等测试指令)TEQ指令将寄存器<Rn>中的值与<shifter_operand>表示的数值按位做逻辑异或操作,根据操作的结果更新CPSR中相应的条件标志位。指令的语法格式为:TEQ{<cond>}<Rn>,<shifter_operand>其中,各参数的使用方法与CMP指令相同。TEQ指令通常用于比较两个数是否相等,这种比较操作不影响CPSR中的V位和C位(影响Z位)。TEQ指令也可用于比较两个操作数符号是否相同,该指令执行后,CPSR中的N位为两个操作数符号异或操作的结果。使用举例如下:TEQR3,#01

7.3运算类指令

17.MUL(32位乘法指令)MUL指令实现两个32位的数(可以为无符号数,也可为有符号数)的乘积,并将结果的低32位存放到一个32位寄存器中,同时可以根据运算结果设置CPSR中相应的标志位。指令的语法格式为:MUL{<cond>}{S}<Rd>,<Rm>,<Rs>其中,<cond>为指令执行的条件码;<Rd>寄存器为目标寄存器;<Rm>寄存器为第1个乘数所在的寄存器;<Rs>寄存器为第2个乘数所在的寄存器。使用举例如下:LDRR0,=0x1234MOVR1,#16MULR2,R0,R1则R2中值为0x12340。7.3运算类指令

18.MLA(32位带加数乘法指令)MLA指令实现两个32位的数(可以为无符号数,也可为有符号数)的乘积,再将乘积加上第3个操作数,并将结果的低32位存放到一个32位寄存器中,同时可以根据运算结果设置CPSR中相应的标志位。指令的语法格式为:MLA{<cond>}{S}<Rd>,<Rm>,<Rs>,<Rn>其中,<Rn>为第3个操作数所在的寄存器,该操作数是一个加数,其余参数的使用方法与MUL指令相同。除了将乘积再加上第3个操作数之外,MLA指令同MUL指令相同。使用举例如下:LDRR0,=0x1234MOVR1,#16MOVR2,#5MLAR3,R0,R1,R2则R2中值为0x12345。7.3运算类指令

19.SMULL(64位有符号数乘法指令)SMULL指令实现两个32位的有符号数的乘积,乘积结果的高32位存放到一个32位的寄存器<RdHi>中,乘积结果的低32位存放到一个32位寄存器<RdLo>中,同时可以根据运算结果设置CPSR中相应的标志位。指令的语法格式为:SMULL{<cond>}{S}<RdLo>,<RdHi>,<Rm>,<Rs>其中,<RdHi>寄存器存放乘积结果的高32位数据;<RdLo>寄存器存放乘积结果的低32位数据;其余参数的使用方法与MUL指令相同。SMULL是最常用的32位符号数的乘法指令。使用举例如下:MVNR0,#15;R0=-16MVNR1,#63;R1=-64SMULLR2,R3,R0,R1则R3=0x00000000,R2=0x00000400。7.3运算类指令

20.SMLAL(64位带加数的有符号数乘法指令)SMLAL指令将两个32位有符号数的64位乘积结果与<RdHi>和<RdLo>中的64位二进制数相加,加法结果的高32位存放到一个32位的寄存器<RdHi>中,加法结果的低32位存放到一个32位寄存器<RdLo>中,同时可以根据运算结果设置CPSR中相应的标志位。指令的语法格式为:SMLAL{<cond>}{S}<RdLo>,<RdHi>,<Rm>,<Rs>其中,<RdHi>寄存器在指令执行前存放64位加数的高32位数据,指令执行后存放加法结果的高32位数据;<RdLo>寄存器在指令执行前存放64位加数的低32位数据,指令执行后存放加法结果的低32位数据;其余参数的使用方法与SMULL指令相同。使用举例如下:MVNR0,#15;R0=-16MVNR1,#63;R1=-64LDRR2,=0x400MOVR3,#0x20SMLALR2,R3,R0,R1则R3=0x00000020,R2=0x00000800。

7.3运算类指令

21.UMULL(64位无符号数乘法指令)UMULL指令实现两个32位的无符号数的乘积,乘积结果的高32位存放到一个32位的寄存器<RdHi>中,乘积结果的低32位存放到一个32位寄存器<RdLo>中,同时可以根据运算结果设置CPSR中相应的标志位。指令的语法格式为:UMULL{<cond>}{S}<RdLo>,<RdHi>,<Rm>,<Rs>其中,参数的使用方法与SMULL指令相同。当<Rm>、<Rn>、<RdHi>、<RdLo>、<Rs>为R15时,指令执行的结果不可预测。另外<RdHi>、<RdLo>和<Rm>必须是3个不同的寄存器,否则指令执行的结果不可预测。UMULLS指令不影响CPSR中的C标志位和V标志位。使用举例如下:LDRR0,=12345678LDRR1,=23456789UMULLR2,R3,R0,R1则R3=0x00010761,R2=0x6AEDE366。7.3运算类指令

22.UMLAL(64位带加数无符号数乘法指令)UMLAL指令将两个32位无符号数的64位乘积结果与<RdHi>和<RdLo>中的64位二进制数相加,加法结果的高32位存放到一个32位的寄存器<RdHi>中,加法结果的低32位存放到一个32位寄存器<RdLo>中,同时可以根据运算结果设置CPSR中相应的标志位。指令的语法格式为:UMLAL{<cond>}{S}<RdLo>,<RdHi>,<Rm>,<Rs>其中,参数的使用方法与SMLAL指令相同。使用举例如下:MOVR0,#16MOVR1,#64MOVR2,0x40000MOVR3,0x20UMLALR2,R3,R0,R1则R3=0x00000020,R2=0x00040400。7.4控制类指令

ARM的控制类指令主要包括分支指令、CPSR访问指令、信号量指令、异常处理指令和协处理器指令,ARMv4T共有13条控制类指令。指令助记符指令功能B跳转指令BL带返回的跳转指令BX带状态切换的跳转指令MSR通用寄存器到状态寄存器的传送指令MRS状态寄存器到通用寄存器的传送指令SWP字交换指令SWPB字节交换指令SWI软中断指令CDP协处理器数据操作指令LDC协处理器数据读取指令STC协处理器数据写入指令MCRARM寄存器到协处理器寄存器的数据传送指令MRC协处理器寄存器到ARM寄存器的数据传送指令7.4控制类指令

1.B(跳转指令)B指令将<target_address>表示的目标地址通过计算传送到PC中,从而改变程序的执行流程,这种改变可以是有条件的,也可以是无条件的。指令的语法格式为:B{<cond>}<target_address>其中,<cond>为指令执行的条件码;<target_address>为指令跳转的目标地址。B指令跳转的目标地址采用相对寻址方式,即指令中的目标地址<target_address>是真正目标地址相对于当前指令的地址(由PC指出)的偏移量。B指令主要的应用还在于条件跳转。由于有15个条件码,因此在实际应用中可以有15条不同的条件跳转指令。使用举例如下:BEQ complete

;条件跳转BLT lessthan

;条件跳转B gcd

;无条件跳转7.4控制类指令

2.BL(带返回的跳转指令)BL将<target_address>表示的目标地址通过计算传送到PC中,同时将当前指令的下一条指令的地址保存在寄存器LR中,从而实现子程序的调用。指令的语法格式为:BL{<cond>}<target_address>其中,各参数的使用方法与B指令相同。BL指令的目标地址的计算方法与B指令相同。使用举例如下:下面的程序段是一个子程序调用的简单例子。BL subroutineexit……subroutineMOV R9,#100MOVR10,#90ADD R11,R9,R10MOV PC,LR7.4控制类指令

3.BX(带状态切换的跳转指令)BX也是一条跳转指令,但目标地址采用寄存器寻址。BX指令主要用于从ARM代码区跳转到Thumb代码区。当从Thumb空间返回ARM空间时,也要用BX指令。指令的语法格式为:BX{<cond>}<Rm>其中,<cond>为指令执行的条件码;<Rm>为跳转的目标地址。使用举例如下:

CODE32LDRR0,=thumbcode+1MOVLR,PCBX R0……CODE16thumbcodeADDR7,#1BX LR7.4控制类指令

4.MSR(通用寄存器到状态寄存器传送指令)MSR指令用于将某通用寄存器的内容或一个立即数传送到状态寄存器中。指令的语法格式为:MSR{<cond>}CPSR_<fields>,#<immediate>MSR{<cond>}CPSR_<fields>,#<Rm>MSR{<cond>}SPSR_<fields>,#<immediate>MSR{<cond>}SPSR_<fields>,#<Rm>其中,<fields>设置状态寄存器中需要操作的位。<immediate>为将要传送到状态寄存器中的立即数。<Rm>寄存器包含将要传送到状态寄存器中的数据。使用举例如下:下面的程序代码将处理器模式切换到特权模式。MRS R0,CPSRBIC R0,R0,#0x1FORR R0,R0,#00x13MSRCPSR_C,R07.4控制类指令

5.MRS(状态寄存器到通用寄存器传送指令)MRS指令用于将状态寄存器的内容传送到某通用寄存器中。指令的语法格式为:MRS{<cond>}<Rd>,CPSRMRS{<cond>}<Rd>,SPSR其中,<cond>为指令执行的条件码,忽略条件码时指令无条件执行;<Rd>寄存器为目标寄存器。MRS指令主要用于以下三种场合:通常通过“读取-修改-写回”操作序列修改状态寄存器的内容时,MRS指令用于将CPSR的内容读到通用寄存器中;当异常中断允许嵌套时,需要在进入异常中断之后,嵌套中断发生之前保存当前处理器模式对应的SPSR。这时需要先通过MRS指令读出SPSR的值,再用其它指令将SPSR的值保存起来;在进程切换时也需要保存当前状态寄存器的值。使用举例如下:下面的指令读取SPSR中值到寄存器R10中。MRS R10,SPSR7.4控制类指令

6.SWP(字交换指令)SWP指令用于将一个内存字单元(该单元地址放在寄存器<Rn>中)的内容读取到一个寄存器<Rd>中,同时将另一个寄存器<Rm>的内容写入到该内存单元中。当<Rd>和<Rm>为同一个寄存器时,指令交换该寄存器和内存单元的内容。指令的语法格式为:SWP{<cond>}<Rd>,<Rm>,<Rn>其中,<cond>为指令执行的条件码;<Rd>为目标寄存器;<Rm>包含将要保存到内存中的数值;<Rn>包含将要访问的内存单元的地址。本指令主要用于实现信号量操作。使用举例如下:SWPR1,R2,[R3] ;将内存单元[R3]中字数据读取到寄存器R1中,同时将R2寄存器的数据写入到内存单元[R3]中。SWPR1,R1,[R2]

;将R1寄存器的内容和内存单元[R2]的内容交换。7.4控制类指令

7.SWPB(字节交换指令)SWPB指令用于将一个内存字节单元(该单元地址放在寄存器<Rn>中)的内容读取到一个寄存器<Rd>中,寄存器<Rd>的高24位设置为0,同时将另一个寄存器<Rm>的低8位数值写入到该内存单元中。当<Rd>和<Rm>为同一个寄存器时,指令交换该寄存器低8位和内存字节单元的内容。指令的语法格式为:SWPB{<cond>}<Rd>,<Rm>,<Rn>其中,各参数用法同SWP指令相同。本指令主要用于实现信号量操作。使用举例如下:SWPBR1,R2,[R3]

;将内存单元[R3]中字节数据读取到寄存器R1中,R1的高24位设置为0,同时将R2寄存器的低8位数据写入到内存单元[R3]中。7.4控制类指令

8.SWI(软中断指令)SWI指令用于产生软中断,ARM通过这种机制实现在用户模式对操作系统中特权模式的程序的调用。指令的语法格式为:SWI{<cond>}<immed_24>其中,<cond>为指令执行的条件码;<immed_24>为24位的立即数。SWI指令执行时,首先将该指令的下一条指令的地址保存在R14_svc寄存器中,将CPSR保存在SPSR_svc寄存器中。然后设置处理器模式为特权模式,并设置运行在ARM环境(而不是Thumb环境)。接着禁止一般中断,最后将PC值设置为0x00000008或0xFFFF0008。本指令主要用于用户程序调用操作系统的系统服务。。使用举例如下:下面的代码段使程序正常返回系统。MOV R0,#0x18LDR R1,=0x20026SWI0x123456

;注意这里立即数没有符号“#”7.4控制类指令

9.CDP(协处理器数据操作指令)CDP指令用于ARM处理器通知ARM协处理器执行特定的操作,该操作由协处理器完成。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。利用这个特点,可以通过软件模拟该协处理器操作。指令的语法格式为:CDP{<cond>}<coproc>,<opcode_1>,<CRd>,<CRn>,<CRm>,<opcode_2>其中,<cond>为指令执行的条件码;<coproc>为协处理器的编码,可以是P0~P15;<opcode_1>为协处理器即将执行的操作码1;<CRd>作为目标寄存器的协处理器寄存器;<CRn>为存放第1个操作数的协处理器寄存器;<CRm>为存放第2个操作数的协处理器寄存器;<opcode_2>为协处理器即将执行的操作码2。当一个协处理器硬件不能执行属于它的协处理器指令时,将产生未定义指令异常中断。利用这个特点,可以通过软件来模拟该协处理器的硬件操作,只要用该软件来替换指令异常中断处理程序即可。7.4控制类指令

10.LDC(协处理器数据读取指令)LDC指令从一系列连续的内存单元将数据读取到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。指令的语法格式为:LDC{<cond>}{L}<coproc>,<CRd>,<addressing_mode>其中,<cond>为指令执行的条件码,当<cond>忽略时指令为无条件执行;L指示指令为长读取操作,比如用于双精度的数据传送;<coproc>为协处理器的编码,可以是P0~P15;<CRd>作为目标寄存器的协处理器寄存器;<address_mode>为指令的寻址方式,指出内存单元的地址,共有4种地址的计算方法。7.4控制类指令

11.STC(协处理器数据写入指令)STC指令将协处理器的寄存器中的数据写入到一系列连续的内存单元中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。指令的语法格式为:STC{<cond>}{L}<coproc>,<CRd>,<addressing_mode>其中,<cond>为指令执行的条件码,当<cond>忽略时指令为无条件执行;L指示指令为长读取操作,比如用于双精度的数据传送;<coproc>为协处理器的编码,可以是P0~P15;<CRd>作为源寄存器的协处理器寄存器;<address_mode>为指令的寻址方式,指出内存单元的地址。7.4控制类指令

12.MCR(ARM寄存器到协处理器寄存器传送指令)MCR指令将ARM处理器的寄存器中的数据传送到协处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。指令的语法格式为:MCR{<cond>}<coproc>,<opcode_1>,<Rd>,<CRn>,<CRm>{,<opcode_2>}其中,<cond>为指令执行的条件码,当<cond>忽略时指令为无条件执行;<coproc>为协处理器的编码,可以是P0~P15;<opcode_1>为协处理器即将执行的操作码1;<Rd>为ARM寄存器,其值将被传送到协处理器寄存器中;<CRn>为目标寄存器的协处理器寄存器;<CRm>为附加的目标寄存器或者源寄存器的协处理器寄存器;<opcode_2>可选的协处理器即将执行的操作码2。7.4控制类指令

13.MRC(协处理器寄存器到ARM寄存器传送指令)MRC指令将协处理器寄存器中的数据传送到ARM处理器的寄存器中。如果协处理器不能成功地执行该操作,将产生未定义的指令异常中断。指令的语法格式为:MRC{<cond>}<coproc>,<opcode_1>,<Rd>,<CRn>,<CRm>{,<opcode_2>}其中,<Rd>为目标寄存器的ARM寄存器;<CRn>为源寄存器的协处理器寄存器;<CRm>为附加的目标寄存器或者源寄存器的协处理器寄存器;其它参数同MCR指令相同。7.5传送类指令ARM的传送类指令主要包括Load/Store指令和多Load/Store指令。ARMv4T共有12条Load/Store指令和2条多Load/Store指令。指令助记符指令功能指令助记符指令功能LDR字数据读取指令LDRB字节数据读取指令LDRBT用户模式字节数据读取指令LDRH半字数据读取指令LDRSB有符号字节数据读取指令LDRSH有符号的半字数据读取指令LDRT用户模式字数据读取指令STR字数据写入指令STRB字节数据写入指令STRBT用户模式字节数据写入指令STRH半字数据写入指令STRT用户模式字数据写入指令LDM批量字数据读取指令STM批量字数据写入指令7.5传送类指令

1.LDR(字数据读取指令)LDR指令用于从内存中将一个32位的字数据读取到指令中的目标寄存器中。指令的语法格式为:LDR{<cond>} <Rd>,<addressing_mode>其中,<cond>为指令执行的条件码;<Rd>为目标寄存器;<addressing_mode>为源操作数的地址。使用举例如下:LDR R4,[R5]

;R5的值所指的内存字单元的数据取到R4LDRR4,[R5,#-4]

;R5的值减去4所指的内存字单元的数据取到R4LDR R4,[R5,R6]

;R5的值加上R6的值所指的内存字单元的数据取到R47.5传送类指令

2.LDRB(字节数据读取指令)LDRB指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中。并将目标寄存器的高24位清零。指令的语法格式为:LDR{<cond>}B<Rd>,<addressing_mode>其中,各参数的用法同LDR指令。使用举例如下:假设内存地址0开始的连续4个字节单元的值为0x10、0x00、0xFF、0xE7,且R5寄存器的值为0,则:LDRB R4,[R5,#0]

;R4=0x00000010LDRB R4,[R5,#1]

;R4=0x00000000LDRBR4,[R5,#2]

;R4=0x000000FFLDRBR4,[R5,#3]

;R4=0x000000E77.5传送类指令

3.LDRBT(用户模式的字节数据读取指令)LDRBT指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中,并将目标寄存器的高24位清零。当在特权级的处理器模式下使用本指令时,内存系统将该操作当作一般用户模式下的内存访问操作。指令的语法格式为:LDR{<cond>}BT<Rd>,<addressing_mode>其中,各参数的用法同LDR指令。异常中断程序是在特权级的处理器模式下执行的,这时如果需要按照用户模式的权限访问内存,就可以使用LDRBT指令。使用举例如下:LDRBT R4,[R5]7.5传送类指令

4.LDRH(半字数据读取指令)LDRH指令用于从内存中将一个16位的半字数据读取到指令中的目标寄存器中,并将目标寄存器的高16位清零。如果指令中的内存地址不是半字对齐的,指令会产生不可预知的结果。指令的语法格式为:LDR{<cond>}H<Rd>,<addressing_mode>其中,各参数的用法同LDR指令。使用举例如下:LDRHR4,[R5]

;将内存单元[R5]中的半字读取到R4中,R4中高16位设置为07.5传送类指令

5.LDRSB(有符号的字节数据读取指令)LDRSB指令用于从内存中将一个8位的字节数据读取到指令中的目标寄存器中。并将目标寄存器的高24位设置成该字节数据的符号位的值(即将该字节数据进行符号位扩展,生成32位数据)。指令的语法格式为:LDR{<cond>}SB<Rd>,<addressing_mode>其中,各参数的用法同LDR指令。使用举例如下:LDRSBR4,[R5,#-4]!;将内存单元[R5]-4中的字节读取到R4中,R4中高24位设置为该字节数据的符号位,同时R5=R5-47.5传送类指令

6.LDRSH(有符号的半字数据读取指令)LDRSH指令用于从内存中将一个16位的半字数据读取到指令中的目标寄存器中,并将目标寄存器的高16位设置成该半字数据的符号位的值(即将该半字数据进行符号位扩展,生成32位数据)。如果指令中的内存地址不是半字对齐的,指令会产生不可预知的结果。指令的语法格式为:LDR{<cond>}SH<Rd>,<addressing_mode>其中,各参数的用法同LDR指令。使用举例如下:LDRSHR4,[R5],#4

;将内存单元[R5]中的半字数据读取到R4中,R4中高16位设置为该半字数据的符号位,然后R5=R5+47.5传送类指令

7.LDRT(用户模式的字数据读取指令)LDRT指令用于从内存中将一个32位的字数据读取到指令中的目标寄存器中。当在特权级的处理器模式下使用本指令时,内存系统将该操作当作一般用户模式下的内存访问操作。指令的语法格式为:LDR{<cond>}T<Rd>,<addressing_mode>其中,各参数的用法同LDR指令。异常中断程序是在特权级的处理器模式下执行的,这时如果需要按照用户模式的权限访问内存,就可以使用LDRT指令。使用举例如下:LDRT R4,[R5,#1]7.5传送类指令

8.STR(字数据写入指令)STR指令用于将一个32位的字数据写入到指令中指定的内存单元。指令的语法格式为:STR{<cond>}<Rd>,<addressing_mode>其中,<cond>为指令执行的条件码;<Rd>为源寄存器;<addressing_mode>描述目标操作数的寻址方式,具体算法同LDR指令。STR指令用于将一个32位的字数据写入指令中指定的内存单元。使用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论