第3章chapter3 第3章ARM920T指令系统接正文接标题1.1微型计算机简介本章主要内容如下: (1) ARM指令集概述,介绍ARM指令集全部指令编码及条件域; (2) ARM指令,讲述ARM指令的编码格式、指令含义、汇编格式和使用举例。 S3C2410A嵌入式微处理器片内使用了ARM920T内核,因此S3C2410A使用ARM920T所支持的指令系统。ARM920T指令系统的指令集结构版本为v4T,ARM920T指令系统含有v4T以上指令集结构版本的基础指令,在v4T以上指令集结构版本的微处理器中都可以运行。 ARM920T是典型的RISC处理器,它实现了装入/存储结构,只有装入/存储指令才能访问存储器(内存储器)。而数据处理指令仅仅对寄存器内容进行操作。 ARM920T处理器支持32位寻址空间。 ARM920T支持指令长度为32位的ARM指令集和指令长度为16位的Thumb指令集。从功能上讲,Thumb指令集是ARM指令集主要部分的一个子集。 当处理器正在执行Thumb指令时,称为处理器在Thumb状态操作。 当处理器正在执行ARM指令时,称为处理器在ARM状态操作。 ARM920T处理器总是从ARM状态开始,必须用BX指令明确地转换到Thumb状态。 程序计数器PC也称为R15寄存器,在ARM状态,对每条指令以1个字(4字节)作为地址增量;在Thumb状态,以2字节作为地址增量。 本章对ARM指令集中的每条指令给予详细描述。本章不去描述Thumb指令,有兴趣的读者可以参见参考文献[1]。 3.1ARM指令集概述〖*4/5〗3.1.1ARM指令集概述所有ARM指令长度均为32位,在存储器中以字边界对齐存储。因此在ARM状态,指令地址的最低2位总是为0,即bit[1:0]=00。所有的ARM指令,指令中凡涉及程序地址操作数的,最低2位均被忽略,只有BX指令除外。BX指令用最低位确定分支处的代码,如果bit[0]=1,则分支到Thumb代码;如果bit[0]=0,则分支到ARM代码。 1. ARM指令分组 ARM指令从功能上能被分成以下6组。 ◆嵌入式系统原理及接口技术(第2版)第◆3章ARM920T指令系统1) 分支指令 分支指令,也称为转移或跳转指令,可以向小地址方向分支形成一个循环;可以向大地址方向分支,根据CPSR中不同的条件码标志分支到不同的程序流;可以分支到子程序;可以通过分支把处理器从ARM状态转换到Thumb状态。 2) 数据处理指令 这些指令对通用寄存器中的数据进行操作,不允许使用存储器操作数。通常对2个寄存器,执行像加、减或按位的某种逻辑操作,将结果存入第3个寄存器。 长乘指令将2个32位数相乘,结果为64位,保存在2个寄存器中。 3) 状态寄存器访问指令 这些指令把CPSR或某个SPSR的内容送到通用寄存器,或者把通用寄存器的内容送到CPSR或某个SPSR。 4) 单个寄存器装入或存储指令 这些指令能够:  从存储器装入一个字数据到寄存器,或保存寄存器的值到存储器;  从存储器装入一字节数据到寄存器bit[7:0],或保存寄存器bit[7:0]的值到存储器;  从存储器装入一个半字数据到寄存器bit[15:0],或保存寄存器bit[15:0]的值到存储器;  带符号扩展的字节/半字装入,字节或半字数据从存储器装入寄存器bit[7:0]或 bit[15:0],高位用符号位扩展。 另外,存储器与寄存器数据交换指令可以在存储器和寄存器之间交换字节或字数据。 5) 块数据装入或存储指令 这些指令从存储器装入数据到通用寄存器组的部分或全部寄存器,或保存通用寄存器组的部分或全部寄存器的内容到存储器。 6) 协处理器指令 协处理器指令支持一种通用的扩展ARM结构的方法。支持存储器与协处理器寄存器之间数据的传输;支持ARM寄存器与协处理器寄存器之间数据的传输;支持指定协处理器内部执行某种操作。如果不存在协处理器,将产生未定义指令异常中断,由未定义指令陷阱来仿真协处理器指令的执行。 2. ARM指令的能力 以下介绍ARM指令的主要能力,详细内容见3.2节。 1) 条件执行 所有ARM指令均可以在指令操作码助记符后,跟随一个条件码助记符后缀,依据CPSR中的条件码标志,有条件地被执行,而不需要使用分支指令实现条件分支。 数据处理指令可以指定设置或不设置CPSR中的条件码标志。 2) 寄存器访问 在ARM状态,所有指令能够存取R0~R14,大部分指令也允许存取R15(PC)。MRS和MSR指令能够传送CPSR或SPSR的内容到通用寄存器,在通用寄存器中通过使用通常的数据处理指令,对它们进行操作,然后可以再写回到CPSR或SPSR中。 3) 在线式桶形移位器(barrel shifter)的访问 ARM结构的逻辑单元有一个32位的桶形移位器,它有能力进行一般移位和循环移位。详见3.2.3节和3.2.7节。 3.1.2ARM指令集全部指令编码及条件域简介〖*2〗1. ARM指令集全部指令编码格式ARM指令集全部指令编码格式见图31。 图31ARM指令集全部指令编码格式 图31中注1~注15对应指令名称如下。 注1: 数据处理/程序状态寄存器传送指令; 注2: 乘、乘累加指令; 注3: 长乘、长乘累加指令; 注4: 单个数据交换指令; 注5: 分支并且转换状态指令; 注6: 半字、带符号字节/半字传送指令(寄存器偏移量); 注7: 半字、带符号字节/半字传送指令(立即数偏移量); 注8: 单个数据传送指令; 注9: 未定义指令; 注10: 块数据传送指令; 注11: 分支、分支并且连接指令; 注12: 协处理器数据传送指令; 注13: 协处理器数据操作指令; 注14: 协处理器寄存器传送指令; 注15: 软件中断指令。 由图31可知,全部指令均为等长的32位,因此在存储器保存一条指令占4字节空间,保存指令的地址必须以字(4字节)边界对齐。由于采用了RISC结构,指令编码较为简单。除条件域外,指令中各个域的含义在3.2节中讲述。 2. 指令编码中的条件域 参见图31,指令编码格式中的bit[31:28]称为条件域。在ARM状态,所有指令都要根据CPSR中的条件码标志(简称标志位)和指令中条件域指定的内容,有条件地执行。指令中条件域bit[31:28]确定在哪一种情况下这条指令被执行。如果C、N、Z和V标志的状态满足指令中条件域编码要求,指令被执行;否则指令被忽略。 有15种可能的条件,每一种由2个字符代替,称为条件码助记符后缀(简称条件码助记符),可以附加在指令助记符后,如表31所示。表31条件域编码与助记符后缀对应关系和含义指令bit[31:28]助记符后缀CPSR中的条件码标志含义0000EQZ=1相等0001NEZ=0不等0010CS/HSC=1无符号数高于或等于0011CC/LOC=0无符号数低于0100MIN=1负0101PLN=0正或00110VSV=1溢出0111VCV=0不溢出1000HIC=1并且Z=0无符号数高于1001LSC=0或Z=1无符号数低于或等于1010GEN=V带符号数大于或等于续表 指令bit[31:28]助记符后缀CPSR中的条件码标志含义1011LTN<>V带符号数小于1100GTZ=0并且(N=V)带符号数大于1101LEZ=1或(N<>V)带符号数小于或等于1110AL忽略总是执行例如,分支指令B如果附加条件码助记符后缀EQ,写作BEQ,表示相等时(即Z=1)这条指令才执行;如果Z< >1,则这条指令不被执行,指令被忽略。 表31中bit[31:28]代码为1111的情况没有使用,保留。表中代码为1110的,对应后缀为AL,AL可以在指令中出现,也可以不出现,两种情况都表示这条指令无条件地被执行,如指令B和BAL都表示无条件地执行指令。 3.2ARM 指 令 本节按指令的编码格式划分,讲述ARM指令集中各指令的编码格式、指令含义、指令汇编格式和使用举例。本节仅对编码格式较为复杂的指令,以图示的方式给出编码格式。另外在讲述协处理器指令前,对协处理器进行简单介绍。 指令编码格式中的bit[31:28]为条件域。所有指令都要根据CPSR中的条件码标志和指令中的条件域指定的内容,有条件地执行。为简单起见,以下介绍各指令时不再重复这部分内容。 3.2.1分支并且转换状态指令(BX) 分支并且转换状态指令(BX),在指令中指定了一个Rn寄存器,将Rn内容复制到PC,同时使PC[0]=0。如果Rn[0]=1,将处理器状态转换成Thumb状态,把目标地址处的代码解释为Thumb代码;如果Rn[0]=0,将处理器状态转换成ARM状态,把目标地址处的代码解释为ARM代码。 1. 指令含义 通过复制一个通用寄存器Rn的内容到程序计数器PC,指令实现分支功能。这条指令也允许处理器状态被转换。 2. 指令汇编格式 指令汇编格式如下: BX{cond} Rn其中: {cond}表示两个字符的条件码助记符,详见表31。 Rn表示合法的寄存器编号。Rn的内容为分支目的地址。其中bit[0]用于指示后续指令为ARM或Thumb指令。 应避免使用R15作为操作数Rn,如果需要这样做,可以使用MOV PC,PC或ADD PC,PC,#0指令。 3. 使用举例 【例3.1】处理器从执行ARM指令代码处分支到标号为Goto_THUMB处,并且执行Thumb指令代码,然后又返回到Back_ARM处,执行ARM指令代码。;假定处理器当前正在执行ARM指令 ADR R1,Goto_THUMB+1;将分支目标地址送R1,使R1的bit[0]=1 BX R1;分支并且转换为Thumb状态  CODE16;汇编以下代码为Thumb指令 Goto_THUMB;分支目标地址标号 ;Thumb指令代码 ADR R2,Back_ARM;将分支目标地址送R2,并且R2的bit[0]=0 BX R2;分支且转换为ARM状态  ALIGN;字对齐 CODE32;汇编以下代码为ARM指令 Back_ARM;分支目标地址标号 ;ARM指令代码3.2.2分支、分支并且连接指令(B、BL) 分支指令(B)使程序分支(转移)到确定的地址处执行程序。 分支并且连接指令(BL)除了使程序分支(转移)到确定的地址处执行程序外,还要保存返回地址到LR寄存器,即把BL指令的下一条指令的地址送LR。 上述两条指令,只允许分支到ARM指令代码处,不允许分支到Thumb指令代码处。 1. 指令含义 对于分支指令(B),指令能在±32MB地址范围内实现分支。 对于分支并且连接指令(BL),执行指令会将PC值写入当前寄存器组的连接寄存器R14,写入的PC值是经过调整的、跟在分支并且连接指令后的指令的地址,同时R14的bit[1:0]被清0。 使用分支并且连接指令(BL)可以调用一个子程序,为了从子程序返回,如果R14(LR)在子程序中没有被修改,可以使用MOV PC,R14指令实现返回。 2. 指令汇编格式 指令汇编格式如下: B{L}{cond} 其中: {L}出现L表示分支并且连接指令,不出现L表示分支指令。 {cond}条件码助记符。 目标地址,由汇编器计算偏移量。 3. 使用举例 【例3.2】使用分支指令使部分代码循环5次。MOVR0,#5;R0值为5 Loop1 SUBSR0,#1;R0减1送R0,设置标志位 BNELoop1;条件执行,不为0则分支到标号Loop1处【例3.3】使用分支并且连接指令调用不同的子程序。CMPR0,#0;比较,设置标志位 BLEQSUBEQPROG;相等,则调用SUBEQPROG BLGTSUBGTPROG;大于,则调用SUBGTPROG BLSUBLTPROG;小于,则调用SUBLTPROG3.2.3数据处理指令 ARM数据处理指令可以分为3类: 数据传送指令(如MOV和MVN)、算术逻辑操作指令(如ADD、SUB或AND等)和比较指令(如CMP和TST等)。 数据处理指令只能对寄存器的内容进行操作,不允许对存储器中的数据进行操作,也不允许指令直接使用存储器的数据或在寄存器与存储器之间传送数据。 对于数据传送指令MOV和MVN,指令中指定的目的寄存器的内容被覆盖,如果目的寄存器指定了PC,如MOV PC,R14,则可以实现程序的转移。 数据传送指令可以实现寄存器到寄存器,立即数到寄存器的传送。 算术逻辑操作指令通常对指定的两个寄存器(或1个寄存器、1个立即数)进行操作,结果存到第3个寄存器,允许选择修改或不修改CPSR中的条件码标志。 比较指令TEQ、TST、CMP和CMN,通常对指定的两个寄存器(或1个寄存器、1个立即数)进行比较,比较结果不保存到寄存器,只影响CPSR中的条件码标志。 上述指令通常允许对指定的操作数进行移位操作。 1. 指令编码格式 数据处理指令编码格式见图32。 图32数据处理指令编码格式 图32中,第1操作数总是寄存器Rn。Rd称为目的寄存器,TST、TEQ、CMP和CMN指令不送结果到目的寄存器Rd,其他指令产生的结果送Rd。 第2操作数Operand2可以是寄存器Rm的值经过移位产生的32位值,或8位立即数经过循环右移产生的32位的值,指令中bit[25]的值用来选择Rm或8位立即数。 CPSR中的条件码标志可能被保护或由指令的结果设置,取决于指令中bit[20]的值。但是对于指令TST、TEQ、CMP和CMN,汇编器产生的指令编码一定会把指令的bit[20]置1,在执行指令时,由测试结果设置CPSR中的条件码标志。 2. 指令含义 1) 各指令含义 数据处理指令依指令编码格式中bit[24:21]分为16条指令,包括数据传送指令、算术逻辑操作指令和比较指令。各条指令含义见表32。表32数据处理各指令含义指 令 格 式指 令 含 义指令功能描述MOV{cond}{S} Rd,数据传送Rd=MVN{cond}{S} Rd,数据求反传送Rd=NOT ADD{cond}{S} Rd,Rn,加Rd=Rn+ADC{cond}{S} Rd,Rn,带进位加Rd=Rn++CSUB{cond}{S} Rd,Rn,减Rd=Rn-SBC{cond}{S} Rd,Rn,带进(借)位减Rd=Rn-+C-1RSB{cond}{S} Rd,Rn,逆向减Rd=-RnRSC{cond}{S} Rd,Rn,带进(借)位逆向减Rd=-Rn+C-1CMP{cond} Rn,比较,做减法Rn-,只设置CPSRCMN{cond} Rn,负数比较,做加法Rn+,只设置CPSRTST{cond} Rn,测试,按位逻辑与Rn AND ,只设置CPSRTEQ{cond} Rn,测相等,按位逻辑异或Rn EOR ,只设置CPSRAND{cond}{S} Rd,Rn,按位逻辑与Rd=Rn AND EOR{cond}{S} Rd,Rn,按位逻辑异或Rd=Rn EOR ORR{cond}{S} Rd,Rn,按位逻辑或Rd=Rn OR BIC{cond}{S} Rd,Rn,位清0Rd=Rn AND NOT注: 表中表示图32中Operand2,Operand2的取得在随后内容中介绍。2) 指令对CPSR中条件码标志位的影响 逻辑操作对操作数的对应位,执行按位操作。 在逻辑操作(AND、EOR、TST、TEQ、ORR、BIC)和数据传送操作(MOV、MVN)指令中,如果S位被置1(并且Rd不是R15),则CPSR中的V标志位不受影响;C标志位由桶形移位器产生的carry out设置;当指令操作结果为全0时Z标志位被设置;N标志位由指令操作结果的bit[31]的值设置。 算术操作(SUB、RSB、ADD、ADC、SBC、RSC、CMP、CMN)指令中,每个操作数被看作32位整数(无符号数或带符号数的2的补码),如果指令中S位被置1(并且Rd不是R15),在发生溢出时,CPSR中的V标志位被设置;C标志位由ALU的bit[31]产生的进位设置;如果指令操作结果为全0时,Z标志位被设置;N标志位将被设置成指令操作结果的bit[31]的值。 3) 对寄存器Rm内容进行移位,结果作为Operand2的值 在图32的指令编码格式中,可以使用bit[3:0]指定被移位的寄存器Rm,bit[11:4]指定对Rm的移位量。bit[11:4]指定移位量的方法有两种,见图33。 图33移位操作 如图33所示,一种是直接使用bit[11:7]中的值作为移位量,另一种是由bit[11:8]指定Rs寄存器中最低一字节内容作为移位量,对Rm内容进行移位后得到的值作为Operand2的值。移位在桶形移位器中进行,移位与传送操作同时进行。 移位类型有逻辑左移(LSL)、逻辑右移(LSR)、算术右移(ASR)和循环右移(ROR)。当循环右移的移位量为0时,称为扩展循环右移(RRX)。 (1) 根据指令中bit[11:7]指定的移位量对Rm移位。 参见图32和图33,指令中bit[11:7]指定的移位量为0~31,对Rm内容进行移位产生的结果作为Operand2的值,有以下几种类型。参见图34~图38中,carry out送CPSR中的C位。 ① 逻辑左移(LSL)。每一次移位,将最高位移到CPSR中的C位,其余各位左移一位,最低位补0。如对Rm逻辑左移6次(LSL #6),产生的结果见图34。当移位次数为0时(LSL #0),CPSR中C位的值不变,Rm的内容直接作为Operand2使用。 图34逻辑左移(LSL #6) ② 逻辑右移(LSR)。每一次移位,将最低位移到CPSR中的C位,其余各位右移一位,最高位补0。如对Rm逻辑右移6次(LSR #6),产生的结果见图35。 图35逻辑右移(LSR #6) 当移位次数为0时(LSR #0),看作移位32次。将全0送Operand2,Rm[31]送CPSR中的C位。 ③ 算术右移(ASR)。每一次移位,将符号位即最高位bit[31]右移一位,同时保留bit[31]位的值不变,其余操作同逻辑右移。如对Rm算术右移6次(ASR #6),产生的结果见图36。 当移位次数为0时(ASR #0),看作移位32次。将Rm[31]送CPSR中的C位。如果Rm[31]=0,则全0送Operand2;如果Rm[31]=1,则全1送Operand2。 图36算术右移(ASR #6) ④ 循环右移(ROR)。每一次移位,将最低位移到CPSR中的C位的同时,也移到最高位,其余各位右移一位。如对Rm循环右移6次(ROR #6),产生的结果见图37。 在循环右移中,ROR #0的功能有些特殊,称为扩展循环右移,写作RRX。它的功能是将CPSR中的C位移入Operand2的最高位,原Rm内容右移一位,Rm最低位移到CPSR中的C位,见图38。 图37循环右移(ROR #6) 图38扩展循环右移(RRX) 在使用指令中bit[11:7]指定对Rm的移位量,bit[6:5]指定移位类型时,指令汇编格式举例见表33。 (2) 使用指令中bit[11:8]指定Rs寄存器,且用Rs中最低字节指定移位量。 参见图32和图33,由指令中bit[11:8]指定Rs寄存器,移位量保存在Rs寄存器的最低字节,对Rm寄存器的内容进行移位,产生的结果作为Operand2的值。表33指令bit[11:7]和bit[6:5]指定Rm移位量和移位类型举例指定对Rm的移位量和移位类型指 令 举 例指 令 含 义Rm,LSL #5bit_shift_ImmADD R0,R2,R3,LSL #1 R3的值逻辑左移1位,加R2,和送R0Rm,LSR #5bit_shift_ImmSUB R0,R2,R3,LSR #2R3的值逻辑右移2位,从R2中减去,差送R0Rm,ASR #5bit_shift_ImmMOV R1,R0,ASR #2R0的值算术右移2位,送R1Rm,ROR #5bit_shift_ImmSUB R1,R2,R4,ROR #6R4的值循环右移6位,从R2中减去,差送R1Rm,RRXAND R2,R3,R4,RRXR4的值扩展循环右移,和R3与的结果送R2注: 表中#5bit_shift_Imm表示5位二进制立即数,作为移位量,对应指令中bit[11:7]。Rs可以选择除R15外的任一通用寄存器。 如果Rs中指定的移位次数为0,那么不改变Rm的内容作为Operand2,并且CPSR中C位的值作为carry out,即C位的值不变。 如果Rs中最低字节指定的移位次数为1~31,进行的移位操作与产生的结果参见图34~图37。 如果Rs中最低字节指定的移位次数大于或等于32,产生的结果如下。  对LSL,如果移位次数等于32,移位结果Operand2为全0,Rm[0]作为carry out。  对LSL,如果移位次数大于32,移位结果Operand2为全0,carry out为0。  对LSR,如果移位次数等于32,移位结果Operand2为全0,Rm[31]作为carry out。  对LSR,如果移位次数大于32,移位结果Operand2为全0,carry out为0。  对ASR,如果移位次数大于或等于32,用Rm[31]填充Operand2各位,用Rm[31] 作为carry out。  对ROR,如果移位次数等于32,移位结果Operand2等于Rm的值,carry out等于 Rm[31]。  对于ROR,如果移位次数大于32,用移位次数重复减32,直到它们的差为1~32,用这个值作为移位次数,移位结果如前述。 对于上述各种情况,carry out的值均送往CPSR中的进位标志C。 使用Rs指定移位量时,指令中bit[6:5]指定移位类型,指令汇编格式举例见表34。表34用Rs指定Rm的移位量和指令中bit[6:5]指定移位类型举例指定Rm的移位量 和移位类型指 令 举 例指 令 含 义Rm, LSL RsADD R0,R1,R2,LSL R3 移位量在R3,R2逻辑左移,加R1,和送R0Rm, LSR RsSUB R0,R1,R2,LSR R4移位量在R4,R2逻辑右移,从R1中减去,差送R0Rm, ASR RsAND R1,R2,R3,ASR R0移位量在R0,R3算术右移,和R2逻辑与,结果送R1Rm, ROR RsMOV R2,R4,ROR R0移位量在R0,R4循环右移,送R24) 对指令中bit[7:0]指定的8位无符号立即数循环右移 参见图32,对指令中bit[7:0]指定的8位无符号立即数进行循环右移时,用bit[11:8]指定移位量,它是一个4位无符号整数。 进行移位操作时,要把指令中bit[7:0]指定的8位无符号立即数作为最低字节,高位bit[31:8]用0扩展,形成一个32位数,对这个32位数进行循环右移。移位的次数,由指令中bit[11:8]指定的4位无符号数乘以2得到,分别为0,2,4,…,30。移位过程参见图37。 例如,对于指令MOV R0,#0xff000000;汇编后等价指令为MOV R0,#0xff,8由于指令长度只有32位,指令无法直接得到一个32位立即数。但是在指令汇编格式中,允许使用一个32位立即数,如本例中#0xff000000,汇编器试图将这个立即数转变成一个8位的立即数,存放在指令的bit[7:0];另外转变出一个移位量,存放在指令的bit[11:8]。指令执行时用这个移位量乘以2得到移位次数。如果一个32位立即数不能转变成这样的格式,汇编器报告错误。在本例中,转变出的指令bit[7:0]为0xff,bit[11:8]为0x04。 5) 关于R15和CPSR中的条件码标志 (1) 当目的寄存器Rd不是指定R15时,CPSR中的条件码标志,如前所述,可能被更改。 (2) 当Rd指定为R15时,并且指令中bit[20]即S=0,表示指令操作结果不影响CPSR时,那么指令操作结果送R15,且CPSR不受影响。 (3) 当Rd指定为R15时,并且指令中bit[20]即S=1,表示指令操作结果影响CPSR时,那么指令操作结果送R15,并且当前方式的SPSR送到CPSR。这样可以恢复PC和CPSR,这种指令的使用,只能在非用户方式。 (4) 如果R15被用作操作数而不是目的寄存器Rd,可以直接使用这个寄存器。但是由于流水线指令预取的功能,PC的值即R15的值,对于指令中指定了移位量的情况,将是当前指令地址加8的值;而对于使用寄存器指定移位量的情况,将是当前指令地址加12的值。 (5) TEQ、TST、CMP和CMN指令对CPSR的影响。 通常在指令助记符后缀中如果出现S,表示操作结果影响CPSR中的条件码标志;如果不出现S,表示不影响。但是即使不出现S,汇编器对TEQ、TST、CMP和CMN指令,也会像出现S那样,将指令的bit[20]设置为1,使得这4条指令的执行会影响CPSR中相应的条件码标志。 3. 指令汇编格式 对于数据传送指令MOV和MVN,格式为: {cond}{S} Rd,对于不保存结果,只影响CPSR中条件码标志的指令CMP、CMN、TEQ和TST,格式为: {cond} Rn,对于指令AND、EOR、SUB、RSB、ADD、ADC、SBC、RSC、ORR和BIC,格式为: {cond}{S} Rd,Rn,其中: 表示指令助记符。 由Rm{,}或<#expression>组成。 {cond}表示条件码助记符。 {S}表示由指令操作结果设置CPSR中的条件码标志。CMP、CMN、TEQ和TST指令,无论出现S与否,汇编器自动使指令bit[20]=1。 Rd、Rn和Rm表示寄存器编号。Rd为目的寄存器,Rn为第1操作数寄存器,Rm的值被移位后作为第2操作数。 <#expression>如果被使用,汇编器将试图产生一个可移位的8位立即数及一个移位量,与expression匹配。如果无法匹配,将产生一个错误信息。 #expression,或RRX组成。 可以是LSL、LSR、ASR、ROR或ASL。算术左移(ASL)与逻辑左移(LSL)功能相同,汇编器产生相同的代码。 4. 使用举例 1) 数据传送和数据求反传送指令举例MOVSR4,R3,LSL #2;R4等于R3逻辑左移2位的值,设置标志位 MOVSPC,R14;PC=R14,且CPSR=SPSR_,用于从异常返回 MOVR15,LR;PC=R14,用于从子程序返回 MVNR0,R1;R1的值求反送R0 MVNR2,#0xf0;R2=0xffffff0f MVNR0,#0;R0=0xffffffff,即R0=-1 MOVSR4,R4,LSR #32;R4的bit[31]送CPSR的C位,R4结果为0 2) 算术操作指令举例ADDEQR3,R5,R6;执行本指令前,先判断Z标志。如果Z=1,则R3=R5+R6; ;如果Z=0,则忽略本条指令 ADDSR2,R2,#2;R2=R2+2,设置标志位 ADDSR2,R1,R0,LSL #2;R2=R1+R0<<2,设置标志位 ;以下两条指令实现64位二进制数的加法: R2、R1=R2、R1+R4、R3 ADDSR1,R1,R3;R1=R1+R3,设置标志位 ADCR2,R2,R4;R2=R2+R4+C SUBR0,R1,R2;R0=R1-R2 SUBR2,R1,#0x10;R2=R1-0x10 SUBSR1,R1,#2;R1=R1-2,设置标志位 SUBSR4,R5,R7,LSR R2;逻辑右移R7,移位次数在R2中最低字节, ;移位后的值作为,R4=R5- ;以下3条指令实现96位二进制数的减法: R6、R2、R1=R6、R2、R1-R5、R4、R3 SUBSR1,R1,R3;R1=R1-R3,设置标志位 SBCSR2,R2,R4;R2=R2-R4+C-1,设置标志位 SBCR6,R6,R5;R6=R6-R5+C-1 RSBR1,R0,#0xff00;R1=0xff00-R0 RSBSR2,R1,R0,LSL #2;R2=R0<<2-R1,设置标志位 RSCR2,R0,#0;R2=0-R0+C-13) 逻辑操作指令举例ANDR3,R2,R4;R3=R2 AND R4 ANDSR1,R1,#0x0f;R1=R1 AND 0x0f,设置标志位 ORRR1,R1,#0xff;将R1的最低8位置1 EORR1,R1,#0xff;将R1的最低8位求反 BICR1,R0,#0x0f;R1=R0 AND NOT 0x0f ANDEQR5,R6,R7,RRX;条件执行,R7的值扩展循环右移,和R6与的结果送R54) 比较与测试指令举例CMPR2,#0x01;R2-0x01的结果不保存,设置标志位, ;汇编器自动使指令的bit[20]=1 CMPSR2,#0x01;R2-0x01的结果不保存,设置标志位 CMNR2,#1;R2的值加1,用来判断R2的值是-1的补码,如果是, ;CPSR中的Z位被置1 TSTR2,#0x01;R2 AND 0x01,设置标志位,用来判断R2中 ;最低位是否为0 TEQR1,R2;R1 EOR R2,设置标志位,用于测试R1和R2是否相等 TEQSR4,#3;测试R4是否等于3。即使指令中不写S,汇编器也会 ;自动使指令中的bit[20]=1 TSTNER1,R5,ASR R1;条件执行,R5内容算术右移,移位次数在R1中最低 ;字节,移位结果和R1与,设置标志位5) 使用移位操作的指令举例MOVR0,R1,LSL #2;R1内容逻辑左移2位送R0 MOVR0,R1,LSR #2;R1内容逻辑右移2位送R0 ADDR2,R0,R1,ASR #2;R1内容算术右移2位,加R0,和送R2 SUBR0,R2,R0,ROR #4;R2减R0内容循环右移4位的值,差送R0 MOVR0,R1,RRX;R1内容扩展循环右移,送R0 MOVR1,R2,ROR R3;R2内容循环右移,移位次数在R3低字节中,移位结果送R1 MOVR0,#0xf000000f;汇编后产生指令MOV R0,#0xff,4 ;表示对立即数0xff循环右移4位,对应图32 ;指令的bit[11:8]为2,bit[7:0]为0xff6) 程序举例 【例3.4】如果R0=1或者R1=2,则程序分支到标号为Label0处;否则,执行标号为Label1处的代码。CMPR0,#1;比较R0是否等于1,设置标志位 BEQLabel0;相等,分支到Label0处 CMPR1,#2;比较R1是否等于2,设置标志位 BEQLabel0;相等,分支到Label0处 Label1;R0<>1同时R1<>2  Label0;由R0=1或R1=2分支过来  ;也可以将上面4条指令,改成如下3条指令,实现相同功能 CMPR0,#1;比较R0是否等于1,设置标志位 CMPNER1,#2;如果前一条指令比较结果不相等(条件码NE), ;才执行本条指令,比较R1是否等于2,设置标志位; ;如果前一条指令比较相等,则不执行本条指令 BEQLabel0;Z=1,则分支到Label0处 Label1;R0<>1同时R1<>2  Label0;由R0=1或R1=2分支过来 【例3.5】求R0的绝对值,再求R1的绝对值,将这两个绝对值相加,和存R2。求绝对值的方法是: 当Rn>=0时,Rn的值不变;否则,将Rn的值求补。TEQR0,#0;由R0 EOR 0,设置标志位 RSBMIR0,R0,#0;如果标志位MI=1,表示R0<0,则执行本指令,R0=0-R0 TEQR1,#0;由R1 EOR 0,设置标志位 RSBMIR1,R1,#0;如果标志位MI=1,表示R1<0,则执行本指令,R1=0-R1 ADDR2,R1,R0;R2=R1+R0【例3.6】对于R1中的无符号数,判断其值的不同范围,做不同的计算。 方法如下: 如果R1低于9,则R2=R08; 如果R1等于9,则R2=R09; 如果R1高于9,则R2=R010。MOVR2,R0,LSL #3;R2=R0<<3,即R2=R08 CMPR1,#9;比较R1是否等于9 ADDCSR2,R2,R0;如果标志位CS=1,表示R1高于、等于9成立, ;则执行本条指令,R2=R2+R0,即R2=R09; ;如果CS=0,表示R1低于9,则不执行本条指令 ADDHIR2,R2,R0;如果HI=1,表示R1高于9,则执行本条指令, ;R2=R2+R0,即R2=R010【例3.7】求R04+R15-R27的值,假定它们都是无符号数,运算结果也不会产生进位,结果存R3中。MOVR0,R0,LSL #2;R0=R0<<2,即R0=R04 ADDR1,R1,R1,LSL #2;R1=R1+R1<<2,即R1=R15 RSBR2,R2,R2,LSL #3;R2=R2<<3-R2,即R2=R27 ADDR3,R0,R1;R3=R0+R1 SUBR3,R3,R2;R3=R3-R2参考例3.7,可以分别用一条指令实现以下不同的计算。 例如,求R0×2n的值(n=0,1,2,3,4;2n=1,2,4,8,16)。MOVR0,R0,LSL #n;R0左移0,1,2,3,4次, ;实现R0乘1,2,4,8,16例如,求R1×(2n+1)的值(n=1,2,3,4;2n+1=3,5,9,17)ADDR1,R1,R1,LSL #n;R1加R1左移1,2,3,4次的值, ;实现R1乘3,5,9,17例如,求R2×(2n-1)的值(n=2,3,4,5;2n-1=3,7,15,31)RSBR2,R2,R2,LSL #n;R2左移2,3,4,5次的值减R2, ;实现R2乘3,7,15,31【例3.8】从子程序返回和从异常返回的区别。 从子程序返回时,不会将当前方式的SPSR恢复到CPSR。 另外,在用户(系统)方式时,不存在当前方式的SPSR。 BLSUB1;将下一条指令的地址送LR寄存器,分支到SUB1处, ;实现子程序调用  SUB1;SUB1子程序  MOVPC,LR;将LR送PC,从子程序返回从异常返回时,除了将保存在LR中的返回地址送PC外,还应将当前方式的SPSR恢复到CPSR。 MOVSPC,LR;将LR送PC,指令助记符后缀S表示将当前方式SPSR ;送CPSR,从异常返回3.2.4程序状态寄存器传送指令(MRS、MSR) 只有程序状态寄存器传送指令(MRS、MSR),才允许读/写程序状态寄存器CPSR或SPSR_。 这两条指令配合可以实现对程序状态寄存器的读—修改—写操作,常用于对FIQ、IRQ设置允许/禁止;转换处理器的操作方式;也可用于修改条件码标志。 1. 指令编码格式 指令编码格式见图39~图311。 图39MRS(传送PSR内容到寄存器)指令编码格式 图310MSR(传送寄存器内容到PSR)指令编码格式 图311MSR(传送寄存器内容或立即数到PSR标志位)指令编码格式2. 指令含义 MRS指令允许将CPSR或SPSR_的内容传送到一个通用寄存器。 MSR指令允许将一个通用寄存器的内容传送到CPSR或SPSR_寄存器。 MSR指令也允许将一个立即数或寄存器的内容只传送到CPSR或SPSR_寄存器的条件码标志(N、Z、C和V),而不影响其他控制位。在这种情况下,指定寄存器的最高4位或立即数的最高4位的内容被写入CPSR或SPSR_的最高4位(条件码标志)。 指令中的操作数有如下限制。 (1) 在用户方式下,CPSR的控制位被保护,不能改变,只有条件码标志能被改变。在特权方式,允许改变整个CPSR。 (2) 程序不要改变CPSR的T状态位,否则处理器进入未定义状态。 (3) 访问哪一个SPSR寄存器取决于当时的执行方式,若处理器在FIQ方式,则SPSR_fiq被访问。 (4) 不能将R15指定为源或目的寄存器。 (5) 在用户方式,不能使用SPSR寄存器,因为这种方式不存在这样的寄存器。 (6) CPSR和SPSR_寄存器的保留位不要修改。可以采用读出CPSR或SPSR_的内容,只修改它们中需要并且允许修改的位,然后再写回原寄存器。这样可以避免误操作修改了保留位。 例如,以下代码采用读—修改—写的方法,实现了处理器操作方式的改变: MRSR1,CPSR;CPSR内容送R1 BICR1,R1,#0x1f;修改,清0方式位 ORRR1,R1,#new_mode;修改,设置新的方式位 MSRCPSR,R1;写回3. 指令汇编格式 对于传送PSR内容到寄存器的指令MRS,格式为: MRS{cond} Rd,对于传送寄存器内容到PSR的指令MSR,格式为: MSR{cond} ,Rm对于只传送寄存器最高4位到PSR条件码标志的指令MSR,格式为: MSR{cond} ,Rm对于只传送立即数到PSR的最高4位的指令MSR,格式为: MSR{cond} ,<#expression>这种格式中<#expression>应该是32位立即数,它的最高4位写入PSR的N、Z、C和V位。 其中: {cond}表示条件码助记符。 Rd和Rm表示除R15外的其他通用寄存器编号。 指CPSR,CPSR_all,SPSR或SPSR_all。其中CPSR和CPSR_all是同义词,SPSR和SPSR_all是同义词。 指CPSR_flg或SPSR_flg。 <#expression>是一个表达式,经过计算后得到32位立即数,汇编器试图产生一个8位立即数,经过循环、右移后能够产生一个32位数,与表达式计算后得到的32位数相等;如果不能实现,则给出错误。 例如指令: MSR CPSR_flg,#0x50000000由于指令长度为32位,所以不能直接使用32位立即数。汇编器试图产生一个8位立即数,填入指令的bit[7:0],产生一个循环右移移位量填入指令bit[11:8],在指令执行期间通过移位(移位方法参考数据处理指令)得到一个32位数,与汇编指令中立即数匹配。汇编器如果无法实现数据匹配,则给出错误。本条指令只使用了32位立即数的最高4位。 4. 使用举例 在用户方式和特权方式,某些相同格式的指令,产生的作用是不相同的。;在用户方式 MSRCPSR,R0;R0[31:28]送CPSR[31:28] MSRCPSR_flg,R0;R0[31:28]送CPSR[31:28] MSRCPSR_flg,#0xf0000000;0xf送CPSR[31:28] MRSR0,CPSR;CPSR[31:0]送R0[31:0] ;在特权方式 MSRCPSR,R0;R0[31:0]送CPSR[31:0] MSRCPSR_flg,R0;R0[31:28]送CPSR[31:28] MSRCPSR_flg,#0xf0000000;0xf送CPSR[31:28] MSRSPSR,R0;R0[31:0]送SPSR_[31:0] MSRSPSR_flg,R0;R0[31:28]送SPSR_[31:28] MSRSPSR_flg,#0x30000000;0x3送SPSR_flg[31:28] MRSR1,SPSR;SPSR_[31:0]送R1[31:0]【例3.9】允许FIQ中断,禁止FIQ中断(特权方式)。ENABLE_FIQ;允许FIQ中断 MRSR0,CPSR;CPSR[31:0]送R0[31:0] BICR0,R0,#0x40;R0[6]清0,其余位不变,允许FIQ中断 MSRCPSR,R0;R0[31:0]送CPSR[31:0]