arm原理与c程序设计 第三章_第1页
arm原理与c程序设计 第三章_第2页
arm原理与c程序设计 第三章_第3页
arm原理与c程序设计 第三章_第4页
arm原理与c程序设计 第三章_第5页
已阅读5页,还剩174页未读 继续免费阅读

下载本文档

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

文档简介

1、第三章ARM 指令表3.1 ARM指令学习程序框架3.2 ARM指令格式3.3 ARM指令寻址方式 3.4 ARM指令汇总本章小结 3.1 ARM指令学习程序框架按照小节中的方法,建立工程文件,其中,源文件名为。在图1-16中,指定RO Base为0 x3000 0000(对于UP-NETARM2410实验箱出厂设置)或者0 x4000 0000(对于SBC2440出厂设置)。需要说明的是,如果用户更新了实验箱上的FLASH内容,那么需要按照第五章的内容进行ARM汇编语言程序设计,即需要添加初始化S3C2410芯片的程序段。的代码如下:1AREA InstAn, CODE, READONLY2

2、ENTRY3 START4;5;6;7 ;Here is an example which shows the usage of MOV:8 MOV R0, #0 x789 MOV R2, R010 STOP 11BLSTOP12 END上面的程序段中分号后面的为注释,START标号要顶格写,START标号后面书写需要分析的ARM指令,分析结果要在RealView Debugger调试器的存放器中查看(本书中不会出现printf等输出信息到控制台的语句,而很多与ARM相关的书里面都有类似的语句。本书程序的输出结果通过四种方式查看,即存放器、存储器、显示屏等硬件输出设备或计算机串行终端显示)。上

3、述程序演示了MOV指令的局部功能,其中,“MOV R0, #0 x78执行后,R0存放器的值为0 x78,“MOV R2, R0执行后,存放器R2的值为0 x78。程序最后要有一个循环语句。 3.2 ARM指令格式全部ARM指令的字长均为32位,按字对齐方式存储(一个字等于4个字节),如果第一条ARM指令的地址为0 x0000 0000,那么其下一条指令的地址为0 x0000 0004,依次类推,即存储器中ARM指令的地址的最低两位总为0。ARM指令的汇编语言语法格式为S , ,其中:为必需项, 为可选项。opcode表示ARM指令汇编语言助记符,如ADC、ADD等,针对ARM920T(即AR

4、Mv4T)而言,具体内容参见表3-1。表3-1 基于ARMv4T架构的ARM指令助记符序号助记符序号助记符序号助记符序号助记符1ADC14LDR27MUL40STRH2ADD15LDRB28MVN41STRT3AND16LDRBT29ORR42SUB4B17LDRH30RSB43SWI5BIC18LDRSB31RSC44SWP6BL19LDRSH32SBC45SWPB7BX20LDRT33SMLAL46TEQ8CDP21MCR34SMULL47TST9CMN22MLA35STC48UMLAL10CMP23MOV36STM49UMULL11EOR24MRC37STR12LDC25MRS38STR

5、B13LDM26MSR39STRBTcond表示指令执行的条件码助记符。所有ARM指令都是条件执行的:当条件满足时,指令执行;当条件不满足时,指令不执行。条件码位于指令机器编码的高4位,如图3-1所示,即第3128位,共有24=16种条件码,其含义和助记符如表3-2所示。S表示如果指令中有S后缀,那么指令执行将影响CPSR的值,否那么不影响。Rd表示目的存放器。Rn表示第一个源操作数存放器。shifter_operand表示第二个源操作数。图3-1 ARM指令机器码汇总表3-2 指令条件码助记符及其含义条件码31:28条件码助记符含 义CPSR中条件标志位值0000EQ相等Z=10001NE不

6、相等Z=00010CS/HS无符号数大于或等于C=10011CC/LO无符号数小于C=00100MI负数N=10101PL非负数N=00110VS上溢出V=10111VC未溢出V=01000HI无符号数大于C=1且Z=01001LS无符号数小于或等于C=0且Z=11010GE有符号数大于或等于(N=1且V=1) 或 (N=0且V=0),即N=V1011LT有符号数小于(N=1且V=0) 或 (N=0且V=1),即NV1100GT有符号数大于Z=0且N=V1101LE有符号数小于或等于Z=1且NV1110AL无条件执行1111 一般地,一条ARM汇编语言指令编译后对应于一条可执行的32位ARM机

7、器码指令,ARM机器码指令如图3-1所示,其中第3128位为条件码,从图3-1中可以分析出各操作数所占的位数及可能的取值范围。例如,Rn、Rd、Rs和Rm用于表示存放器R0R15中的某个,故均占有4位。3.3 ARM指令寻址方式ARM指令寻址方式本质上是ARM汇编指令的编码规那么,熟悉ARM指令寻址方式,有助于写出正确的ARM指令。在学习复杂的汇编语言指令集时,指令寻址方式显得尤为重要;尽管基于RISC指令集的ARM指令数量较少,但是了解ARM指令的寻址方式,可以更深入地掌握ARM汇编指令集。按照指令操作数类型,ARM指令集分为五种寻址方式,依次为数据处理操作数寻址、字与无符号字节存储/装入寻

8、址、双字与半字及有符号字节存储/装入寻址、存放器批量存储/装入寻址、协处理器存储/装入寻址。3.3.1 数据处理操作数寻址数据处理操作数寻址方式的指令语法为:S , , 其中,有11种形式,如下所述。模式1:立即数机器码:如图3-2所示。图3-2 形式1的ARM指令编码语法:#这里,immediate为以图3-2中8位immed_8为低8位、高24位补0后的32位数循环右移2rotate_imm位得到的立即数。因此,并非所有32位的数都能充当立即数,同时,规定当立即数小于0 xFF时,immed_8 = immediate,rotate_imm = 0;当立即数大于0 xFF时,选择使rota

9、te_imm数值最小的编码形式。容易推算,0 xFF1和0 x102等是不合法的立即数,而0 xFF0和0 x104等那么是合法的立即数。立即数0 x3F0满足编码方式:(1) immed_8 = 0 x3F,rotate_imm = 0 xE;(2) immed_8 = 0 xFC,rotate_imm = 0 xF。此时,采用(1)方式编码,因为方式(1)下rotate_imm较小。如果在编程时写错了立即数,编译时会报错!例如: MOV R0, #0 x03 ADD R3, R3, #1模式2:存放器机器码:如图3-3所示。图3-3 形式2的ARM指令编码 语法: 这里,Rm为操作数的值;

10、如果Rm或Rn指定为R15,那么使用当前指令地址值加上8后的值。例如:ADD R3, R3, R0ADD R3, R3, R15 ; 注:如果该指令地址为0 x3000 0010,其运算为: ;R3 = R3 + 0 x3000 0010 + 8模式3:存放器逻辑左移立即数机器码:如图3-4所示。图3-4 形式3的ARM指令编码语法:, LSL # 这里,操作数等于Rm的值逻辑左移shift_imm位。如果Rm或Rn指定为15,那么操作数使用当前指令地址值加上8后的值。例如:MOV R1, R0, LSL #2模式4:存放器逻辑左移存放器机器码:如图3-5所示。图3-5 形式4的ARM指令编码

11、语法:, LSL 这里,操作数为Rm的值逻辑左移Rs7:0位。因此,当Rs7:0大于等于32时,操作数将为0。R15不能用作Rn、Rd、Rs或Rm。例如:MOV R2, R0, LSL R1模式5:存放器逻辑右移立即数机器码:如图3-6所示。图3-6 形式5的ARM指令编码语法:, LSR #这里,操作数为存放器Rm的值右移shift_imm位。如果Rm或Rn指定R15,那么操作数使用当前指令地址值加上8后的值。例如:MOV R2, R0, LSR #1模式6:存放器逻辑右移存放器机器码:如图3-7所示。图3-7 形式6的ARM指令编码语法:, LSR 这里,操作数为Rm的值右移Rs7:0位。

12、R15不能用作Rd、Rs、Rm或Rn。例如:MOV R2, R0, LSR R1模式7:存放器算术右移立即数机器码:如图3-8所示。图3-8 形式7的ARM指令编码 语法:, ASR # 这里,操作数为Rm算术右移shift_imm位(要求:1shift_imm32),按Rm31进行符号扩展,即如果Rm31=0,那么左边补0;如果Rm31=1,那么左边补1。 因此,当shift_imm= 32时,操作数等于0(Rm31 = 0)或等于0 xFFFF FFFF(Rm31 = 1)。如果Rm或Rn指定为R15,那么操作数使用当前指令地址值加上8后的值。例如:MOV R2, R1, ASR #4模式

13、8:存放器算术右移存放器机器码:如图3-9所示。图3-9 形式8的ARM指令编码语法:, ASR 这里,操作数为Rm的值算术右移Rs7:0位。当Rs7:0 = 0时,相当于不移位;当Rs7:032时,操作数为00(Rm31 = 0)或等于0 xFFFF FFFF(Rm31 = 1)。R15不能用作Rn、Rd、Rs或Rm。例如:MOV R2, R1, ASR R0模式9:存放器循环右移立即数机器码:如图3-10所示。图3-10 形式9的ARM指令编码语法:, ROR #这里,操作数循环右移shift_imm位(要求:1shift_imm31)。如果Rm或Rn指定为R15,那么操作数使用当前指令地

14、址值加上8后的值。例如:MOV R2, R1, ROR #4模式10:存放器循环右移存放器机器码:如图3-11所示。图3-11 形式10的ARM指令编码语法:, ROR 这里,操作数为Rm的值循环右移。R15不能用作Rn、Rd、Rs或Rm。例如:MOV R2, R1, ROR R0模式11:存放器扩展循环右移机器码:如图3-12所示。图3-12 形式11的ARM指令编码语法:, RRX 这里,操作数为Rm的值逻辑右移一位(该位放入Shifter_carry_out),CPSR的C标志位填充Rm的最高位空位。如果Rm或Rn指定R15,那么操作数使用当前指令地址值加上8后的值。例如:MOV R2,

15、 R1, RRX备注:在上述移位操作中,无论是左移还是右移,最后移出的位的值均存放在Shifter_carry_out中。3.3.2 字与无符号字节存储/装入寻址字与无符号字节存储/装入寻址方式的指令语法为:LDR|STRBT , 其中,、B和T的位置可调换;有9种模式(均适用于LDR、LDRB、STR和STRB;只有最后3种模式适用于LDRBT、LDRT、STRBT和STRT),如下所述。模式1:立即数偏置机器码:如图3-13所示。图3-13 模式1的ARM指令编码语法:, #+/-这里,操作数地址为Rn加上或减去12位的立即数值。U = 1时为加;U = 0时为减。B = 0时为字操作;B

16、 = 1时为无符号字节操作。L = 0时为装入操作;L = 1时为存储操作。R15为Rn时,使用当前指令地址加上8后的值。例如:LDR R1, R0, #0 x04; 将内存地址R0+0 x4处的值装入R1中LDR R1, R15, #0 x04; 将内存地址PC+8+0 x4处的值装入R1中备注:要考虑小端或大端存储模式,例如:在小端模式下,对于字访问来说,地址0 x3000 0000处的字是指0 x3000 0003至0 x3000 0000四个字节地址里的字节从高地址至低地址连接起来的32位字;地址0 x3000 0001处的字也是指x3000 0003至0 x3000 0000四个字节

17、地址里的字节从高地址至低地址连接起来的字,只是最高字节处于0 x3000 0000处,依次为0 x3000 0003和0 x3000 0002,最低字节地址为0 x3000 0001。 地址0 x3000 0002处的字仍然是指x3000 0003至0 x3000 0000四个字节地址里的字节连接起来的字,这时最高字节处于0 x3000 0001地址处,依次为0 x3000 0000和0 x3000 0003,最低字节地址为0 x3000 0002;同理,地址0 x3000 0003处的字仍然是指x3000 0003至0 x3000 0000四个字节地址里的字节连接起来的字,这时最高字节处于0

18、 x3000 0002地址处,依次为0 x3000 0001和0 x3000 0000,最低字节地址为0 x3000 0003。大端模式下的排序模式正好相反。尽管如上所述,作者建议,在进行字访问时,12位的立即数的最后两位应为0b00,即能被4整除。注意:STR表示的操作是向右赋值的。模式2:存放器偏置机器码:如图3-14所示。图3-14 模式2的ARM指令编码语法:, +/-Rm 这里,操作数地址为Rn(在此称为基址存放器)的值加上或减去Rm(在此称为变址存放器)的值。R15不能用作Rn。例如:LDRB R1, R0, R2 ; 将内存地址R0+R2处的字 节装入R1中模式3:尺度存放器偏置

19、机器码:如图3-15所示。图3-15 模式3的ARM指令编码语法:有如下五种:, +/, LSL #, +/, LSR #, +/, ASR #, +/, ROR #, +/, RRX这里,操作数地址为Rn加上或减去Rm的移位值。对于LSL,移位立即数shift_imm为031;对于LSR和ASR,shift_imm为132;对于ROR,shift_imm为131。R15不能用作Rm;R15用作Rn时,使用当前指令地址加上8后的值。例如:LDRB R1, R0, R2, LSL #1 ; 将内存地址R0+R21 处的字节值装入R1中模式4:立即数预索引机器码:如图3-16所示。图3-16 模式

20、4的ARM指令编码语法:, #+/offset_12! 这里,操作数地址为Rn的值加上或减去12位的立即数偏移量后的值,同时,这个值写入到Rn中。语法中的“!号将设置机器码中的W位(即第21位),表示Rn加上或减去立即数后的值回赋给Rn。R15不能用作Rn。例如:LDR R1, R0, #0 x04!模式5:存放器预索引机器码:如图3-17所示。图3-17 模式5的ARM指令编码语法:, +/! 这里,操作数地址为Rn的值加上或减去Rm的值,这个地址值回赋给Rn。R15不能用作Rm和Rn。例如:LDR R1, R0, R2! ; 内存地址R0+R2处的值赋; 给R1, R0 = R0 + R2

21、模式6:尺度存放器预索引机器码:如图3-18所示。图3-18 模式6的ARM指令编码语法:有如下五种:, +/, LSL #!, +/, LSR #!, +/-, ASR #!, +/-, ROR #!, +/-, RRX!该模式是在模式3操作的根底上,即操作数地址为Rn的值加上或减去Rm移位后的值,增加了写回操作,即地址值回赋给Rn。例如:LDRB R1, R0, R2, LSL #1! ; 内存地址R0+R21处的值装入R1,R0 = R0 + R21模式7:立即数后索引机器码:如图3-19所示。图3-19 模式7的ARM指令编码语法:, #+/ 这里,操作数地址为Rn的值,如果指令条件满

22、足,那么Rn加上或减去12位立即数后的值赋给Rn。R15不能用作Rn。例如:LDR R1, R0, #0 x4 ; 内存地址R0处的值赋给R1, R0 = R0 + 4模式8:存放器后索引机器码:如图3-20所示。图3-20 模式8的ARM指令编码语法:, +/ 这里,操作数地址为Rn的值,指令条件满足时,Rn加上或减去Rm的值赋给Rn。R15不能用作Rm和Rn。例如:LDR R1, R0, R2 ; 内存地址R0处的值赋给R1, R0 = R0 + R2模式9:尺度存放器后索引机器码:如图3-21所示。图3-21 模式9的ARM指令编码语法:有如下五种:, +/, LSL #, +/, LS

23、R #, +/, ASR #, +/, ROR #, +/, RRX这里操作数地址为Rn的值,Rn加上或减去Rm的移位值后的值赋给Rn。R15不能用作Rm或Rn。 例如:LDR R1, R0, R2, LSL #0 x01 ;内存地址R0处的值赋给R1, R0 = R0 + R213.3.3 双字与半字及有符号字节存储/装入寻址双字与半字及有符号字节存储/装入寻址方式的指令语法为:LDR|STRH|SH|SB|D , 其中,指令中H、SH、SB或D必有其一,条件可以放在指令助记符后面,例如,LDRHLS和LDRLSH均合法;有如下所述6种模式。模式1:立即数偏置机器码:如图3-22所示。图3-

24、22 模式1下的ARM指令编码语法:, #+/这里,操作数地址为Rn的值加上或减去8位立即数偏移量,其中,8位立即数的高四位为immedH,低四位为immedL。 STR开头的存储操作为自左向右,LDR开头的装入操作是自右向左的。图3-22至图3-27中,L、S和H的意义为:当LSH = 0b001时为存储半字;当LSH = 0b010时为装入双字;当LSH = 0b011时为存储双字;当LSH = 0b101时为装入无符号半字;当LSH = 0b110时为装入有符号字节;当LSH = 0b111时为装入有符号半字。R15用作Rn时,Rn为当前指令地址加上8的值。注意:对于半字操作,建议立即数

25、的最低位为0(实际上要求的是Rn加上或减去立即数的值的最低位为0),在小端存储模式下,返回的半字的高字节为操作数地址加1处的值,半字的低字节为该地址处的值;对于双字操作,细心的读者可能已经从表3-1中查证了,ARMv4T并不支持。如果编程时写了不支持的ARM指令,在RVDS中编译时,会提示“Instruction not supported on target CPU(目标CPU不支持此指令)。例如:LDRH R1, R0, #0 x4 ; 内存地址R0+4处的半字装入R1中; 实际上装入的是R0+5和R0+4两处 ; 的字节合并值 ; 要求:R0+4的最低位为0模式2:存放器偏置机器码:如图

26、3-23所示。图3-23 模式2下的ARM指令编码语法:, +/ 这里,操作数地址为Rn加上或减去Rm的值。R15不能用作Rm;R15用作Rn时,Rn的值取当前指令地址加上8。例如:LDRH R1, R0, R2 ; 内存地址R0+R2处的半字; 装入R1中模式3:立即数预索引机器码:如图3-24所示。图3-24 模式3下的ARM指令编码语法:, #+/! 这里,操作数地址为Rn加上或减去8位立即数的值,同时,该操作数地址装入Rn中。8位立即数的高四位为immedH,低四位为immedL。例如:LDRH R1, R0, #0 x02! ; 内存地址R0+0 x02处的;半字装入R1, R0 =

27、 R0+2模式4:存放器预索引机器码:如图3-25所示。图3-25 模式4下的ARM指令编码语法:, +/-! 这里,操作数地址为Rn加上或减去Rm的值,同时,该操作数地址装入Rn中。例如:LDRH R1, R0, R2! ; 内存地址R0+R2处的半字 ; 装入R1, R0 = R0 + R2模式5:立即数后索引机器码:如图3-26所示。图3-26 模式5下的ARM指令编码语法:, #+/- 这里,操作数地址为Rn的值,当指令执行条件满足时,Rn加上或减去立即数offset_8的值赋给Rn。立即数offset_8的高四位为immedH,低四位为immedL。R15不能用作Rn。例如:LDRH

28、 R1, R0, #0 x02 ; 内存地址R0处的值装入 ; R1, R0 = R0 + 2模式6:存放器后索引机器码:如图3-27所示。图3-27 模式6下的ARM指令编码语法:, +/- 这里,操作数地址为Rn的值,当指令条件满足时,Rn加上或减去Rm的值赋给Rn。图3-27中的SBZ(Should Be Zero)为0。R15不能用作Rm或Rn。例如:LDRH R1, R0, R2 ; 内存地址R0处的值装入R1,; R0 = R0 + R23.3.4 存放器批量存储/装入寻址存放器批量存储/装入寻址方式的指令语法为:LDM|STM !, 其中,有如下五种模式。模式1:事后增加(IA

29、= Increment After)机器码:如图3-28所示。图3-28 模式1下的ARM指令编码语法:IA图3-28至图3-31中,对于LDM指令,当PC位于register_list中时,S为1表示SPSR装入CPSR中;对于不使用PC的LDM指令和全部STM类指令,S为1表示使用用户模式下的存放器组,而非当前模式下的存放器。用户模式和系统模式下不能设置S位为1。W位表示操作完成后基址存放器的值是否变化,如果W为1,那么基址存放器的值在操作完成后将增加或减少4乘以存放器列表中包含的存放器个数的值,是增加还是减少,视第23位的值而定,第23位(即U位)为1 时增加,为0时减少。 L位为1时表

30、示装入,为0时表示存储。16位长的存放器列表register_list,每一位对应于一个存放器,即第0位对应于R0,第1位对应于R1,依次类推,第15位对应于R15(即PC),列表中至少应包含一个存放器,多个存放器间用逗号分隔,连续的存放器可以用“-连接,如“R1-R4表示“R1, R2, R3, R4,列表用“包括。可见,S是指指令语法中的“是否存在;W是指指令语法中的“!是否存在;L是指指令语法中使用LDM还是STM。这里,定义操作数首地址start_address为基址存放器Rn的值;操作数尾地址end_address为Rn与4乘以存放器列表中存放器个数的和,再减去4的差,即start_

31、address = Rn, end_address = Rn + 4 (register_list各位中置1的个数) 4如果是LDM操作,操作是自左向右的(与LDR等相反),即首地址至尾地址各个字地址内的值对应装入存放器列表中;如果是STM操作,操作是自右向左的(与STR等相反),即存放器列表中各个存放器的值存入自首地址至尾地址相对应的地址处。如果指令中使用“!,那么尾地址end_address加上4的值赋给Rn,即Rn=Rn+ 4(register_list各位中置1的个数)例如: STMIA R0, R1R4 ; 0赋给R1, R0+4赋给R2, R0+8 ; 赋给R3,R0+12赋给R4

32、STMIA R0!, R1R4 ; R0赋给R1, R0+4赋给R2, ; R0+8赋给R3,R0+12赋给R4, ; R0=R0+16说明:细心的读者调试指令时可能会发现,上述两个指令中,不带有“IA结果是一样的,例如,第一条指令等同于STM R0, R1-R4,道理是显然的。模式2:预先增加(IB = Increment Before)机器码:如图3-29所示。图3-29 模式2下的ARM指令编码语法:IB这里,首地址为start_address = Rn+4,尾地址为end_address = Rn+4(register_list各位中置1的个数),当指令中出现“!时,Rn=Rn+4(r

33、egister_list各位中置1的个数)。例如:STMIB R0, R1R3; R0+4赋给R1, R0+8赋给R2, ; R0+12赋给R3STMIB R0!, R1R3; R0+4赋给R1, R0+8赋给R2, ; R0+12赋给R3, R0 = R0+12模式3:事后减少(DA = Decrement After)机器码:如图3-30所示。图3-30 模式3下的ARM指令编码语法:DA这里,首地址为start_address = Rn -4 (register_list各位中置1的个数)+ 4,尾地址为end_address = Rn,当指令中出现“!时,Rn = Rn - 4 (re

34、gister_list各位中置1的个数)。例如:STMDA R0, R1R3 ; R08赋给R1, R0-4赋给R2, ; R0赋给R3STMDA R0!, R1R3; R08赋给R1, R04赋给R2, ; R0 赋给R3, R0 = R0 12模式4:预先减少(DB = Decrement Before)机器码:如图3-31所示。图3-31 模式4下的ARM指令编码语法:DB 这里,首地址为start_address = Rn4 (register_list各位中置1的个数),尾地址为end_address=Rn4,当指令中出现“!时,Rn=Rn4 (register_list各位中置1的

35、个数)。例如:STMDB R0, R1-R3 ; R012赋给R1, R08赋给R2,; R04赋给R3STMDB R0!, R1R3; R012赋给R1, R08赋给R2, ; R04赋给R3, R0 = R012模式5:堆栈操作 堆栈可用于保存存放器的值,通过压栈(或称入栈)将存放器的值压入栈中保存,通过出栈操作恢复存放器中的数值。尽管堆栈本质上是一段连续的内存空间,但是,有其专用的堆栈操作,根据堆栈指令位置及其移动方向,分为四种方式:即FD、ED、FA和EA。其中,F表示Full stacks,即堆栈指针位置指向栈顶数据(如果有压栈操作,堆栈指针必须首先移动到栈顶前面的一个字空间,因此压

36、栈(STM)时,F相当于Before;如果有出栈操作,由于堆栈指针指向栈顶数据,只需直接取数据即可,因此,出栈(LDM)时,F相当于After)。 E表示Empty stacks,即堆栈指针位置指向栈顶数据前面的一个地址空间,如果有一个压栈操作,该地址空间将保存数据而成为栈顶数据(同样道理,压栈(STM)时,E相当于After;出栈(LDM)时,E相当于Before)。F和E表示堆栈指针位置,而D和A表示堆栈指针移动方向。D为Descending stacks,即堆栈指针移动方向为内存地址减少的方向。A为Ascending stacks,表示堆栈指针移动方向为内存地址增大的方向。因此,有类似的

37、8种操作,即LDMFA、LDMFD、LDMEA、LDMED和STMFA、STMFD、STMEA、STMED,对应于机器码中L(第20位)、P(第24位)、U(第23位)的值依次为:0b100、0b101、0b110、0b111和0b011、0b0b0、0b001、0b000。出于协处理对堆栈访问的支持,建议使用FD或EA方式。例如程序1 AREA INIT, CODE, READONLY2 ENTRY3 START4 MOVR2, #0 x12 ; (1)5 MOV R3, #0 x55 ; (2)6 MOV R4, #0 xAA ; (3)7 8 MOV R0, #0 x30000000 ;

38、 (4)9 MOV R1, #0 x800 ; (5)10 ADD R0, R0, R1 ; (6)11 MOV SP, R0 ; (7)12 13 STMFD SP!, R2,R3,R4 ; (8)14 MOV R4, #0 x88 ; (9)15 16 LDMFD SP!, R2 - R4 ; (10)17 STOP18 BLSTOP19 END程序中各标号的解释如下:(1) R2 = 0 x12; (2) R3 = 0 x55; (3) R4 = 0 xAA;(4) R0 = 0 x3000 0000;(5) R1 = 0 x800;(6) R0 = R0 + R1 = 0 x3000

39、0800;(7) SP = 0 x3000 0800;(8) 0 x3000 07F4 = 0 x12, 0 x3000 07F8 = 0 x55, 0 x3000 07FC = 0 xAA, SP = 0 x3000 07F4;(9) R4 = 0 x88;(10) R2 = 0 x12, R3 = 0 x55, R4 = 0 xAA, SP = 0 x3000 0800。请注意SP的值的变化情况。3.3.5 协处理器存储/装入寻址这里讨论协处理器存储/装入寻址方式的编码和语法,第节中将针对ARM920T微处理器具体讨论协处理器指令(约5个)的应用及例如。协处理器存储/装入寻址方式的指令语法

40、为:L , , 其中,有下述四种模式。模式1:立即数偏置机器码:如图3-32所示。图3-32 模式1下的ARM指令编码语法:, #+/*4图3-32至图3-35中,U = 1表示加;U = 0表示减。N位是协处理器无关的标识位,用于区分不同长度的传递值。W位(第21位)表示指令中有无“!,W = 1表示内存地址写回存放器,W = 0那么不写回。L = 1表示装入,L = 0表示存储。如果指令执行条件满足,那么首地址start_address = Rn +/-offset_8 4(U = 1时取加号,U = 0时取减号),尾地址end_address = start_address + 4 (协

41、处理器的数目cp_num)。R15用作Rn时,Rn的值为当前指令地址加上8。模式2:立即数预索引机器码:如图3-33所示。图3-33 模式2下的ARM指令编码 语法:, #+/*4!如果指令执行条件满足,那么首地址start_address = Rn +/ offset_84(U = 1时取加号,U = 0时取减号),尾地址end_address = start_address+4(协处理器的数目cp_num)。首地址赋给Rn。R15不能用作Rn。模式3:立即数后索引机器码:如图3-34所示。图3-34 模式3下的ARM指令编码语法:, #+/*4如果指令执行条件满足,那么首地址start_a

42、ddress = Rn,尾地址end_address = start_address +4(协处理器的数目cp_num)。Rn = Rn +/-offset_84(U=1时取加号U=0时取减号)。R15不能用作Rn。模式4:无索引机器码:如下图。图3-35 模式4下的ARM指令编码语法:,如果指令执行条件满足,那么首地址start_address = Rn,尾地址end_address = start_address+4(协处理器的数目cp_num)。指定协处理器额外的指令参数,取值为0255的整数,用“包括。R15用作Rn时,Rn的值为当前指令地址加上8。3.4 ARM指令汇总 ARMv6指

43、令集版本具有114条ARM指令,但是ARMv4T仅支持其中的49条指令,如表3-1所示。出于节省篇幅和增强针对性,这里仅介绍表3-1所示的ARM指令(当然,记忆指令是需要时间和方法的),将这些指令分为九类,即赋值指令2条、算术运算指令12条、跳转指令3条、比较指令2条、逻辑运算指令6条、CPSR访问指令2条、内存访问指令16条、软件中断指令1条以及协处理器指令5条,共计49条。此外,本节还将介绍4条ARM伪指令。3.4.1 赋值指令赋值指令有2条,即MOV和MVN,如下所述。MOV指令(赋值)语法:MOVS , 解释:cond表示指令执行条件,如表3-2所示,只有满足条件时指令才能被执行。如果

44、cond被忽略,那么表示使用了条件码AL,即该指令总被执行。S出现在指令中时,将设置指令的S位(第20位)为1,表示指令的执行将影响和刷新CPSR存放器的某些位。Rd存放器为目的操作数。Oprand2为第二个操作数,可以为立即数(是8位整数左边扩展24个0后的32位数循环右移32以内的偶数位得到的)、存放器、存放器移位立即数和存放器移位存放器。移位方式有逻辑左移(LSL)、逻辑右移(LSR)、算术右移(ASR)、循环右移(ROR)、带扩展位的循环右移(RRX)。 用“括起来的为可选项,用“括起来的为必选项。操作:如果执行条件满足,那么 Rd = Oprand2 如果 S = 1 且 Rd =

45、R15,那么 如果当前工作模式有SPSR,那么 CPSR=SPSR 否那么,执行结果不可预见 如果S =1 但 Rd R15,那么 CPSR的标志位赋值如下: N = Rd31 Z = 1(Rd为0)或0(Rd不为0) C = 最后移出的位(注意:这种说法稍欠准确) V不受影响用途:将某个特定值的立即数装入存放器;将一个存放器的值赋给另一个存放器;移位操作;左移n位实现操作数乘以2n的运算;指令“MOV PC, LR可以实现跳转;当PC为目的操作数,且S出现在指令中时,例如,“MOVS PC, LR执行跳转的同时,还将SPSR的值赋给CPSR。例如:MOV R1, #0 x01 ; R1 =

46、0 x1MOV R2, R1 ; R2 = R1 = 0 x1MOV R3, R2, LSL #0 x2 ; R3 = R2R1 = 2MVN指令(取反赋值)语法:MVNS , 解释:略操作:如果执行条件满足,那么 Rd = Oprand2的取反 如果 S = 1 且 Rd = R15,那么 如果当前工作模式有SPSR,那么 CPSR = SPSR 否那么,执行结果不可预见 如果S =1 但 Rd R15,那么 CPSR的标志位赋值如下: N = Rd31 Z = 1(Rd为0)或0(Rd不为0) C = 最后移出的位 V不受影响用途:用作某些位的屏蔽;计算一个数值的二进制补码。例如:MVN

47、R4, R3, LSR R1 ; R4 = (R3R1)3.4.2 算术运算指令算术运算指令有12条,即ADD、ADC、MLA、MUL、RSB、RSC、SBC、SMLAL、SMULL、SUB、UMLAL以及UMULL,如下所述。ADD指令(加法)语法:ADDS , , 解释:Rd存放器为目的操作数。Rn存放器为第一个源操作数。Oprand2为第二个源操作数,可以为立即数(是8位整数左边扩展24个0后的32位数循环右移32以内的偶数位得到的)、存放器、存放器移位立即数和存放器移位存放器。移位方式有逻辑左移(LSL)、逻辑右移(LSR)、算术右移(ASR)、循环右移(ROR)、带扩展位的循环右移(

48、RRX)。操作:如果执行条件满足,那么 Rd = Rn + Oprand2 如果 S = 1 且 Rd = R15,那么 如果当前工作模式有SPSR,那么 CPSR = SPSR 否那么,执行结果不可预见 如果S =1 但 Rd R15,那么 CPSR的标志位赋值如下: N = Rd31 Z = 1(Rd为0)或0(Rd不为0) C = 结果的进位 V = 结果的溢出位用途:实现两个数值的加法运算;使用形如“ADD Rx, Rx, #1实现累加运算;使用形如“ADD Rd, Rx, Rx, LSL #n实现Rx的(2n + 1)倍运算;使用形如“ADD Rd, PC, #offset获得一个基

49、于PC的相对地址(此处,PC的值为当前指令地址加上8)。例如:ADD R2, R1, #2 ; R2 = R1 + 2ADD R3, R1, R2 ; R3 = R1 + R2ADD R4, R4, R3, LSL #1 ; R4 = R4+ R31ADC指令(带进位加法)语法:ADCS , , 解释:略操作:如果执行条件满足,那么 Rd = Rn + Oprand2 + CPSR的C标志位 如果 S = 1 且 Rd = R15,那么 如果当前工作模式有SPSR,那么 CPSR = SPSR 否那么,执行结果不可预见 如果S =1 但 Rd R15,那么 CPSR的标志位赋值如下: N =

50、Rd31 Z = 1(Rd为0)或0(Rd不为0) C = 结果的进位 V = 结果的溢出位用途:在实现64位的加法操作时,ADC用于两个加数的高32位数相加,例如,R1和R0以及R3和R2存入两个64位数,其中,R0和R2存放低32位,R1和R3存放高32位,这两个64位数相加的结果存放在R5和R4中,其中,R4存放结果的低32位,R5存放结果的高32位,那么指令为ADDS R4, R0, R2 ; 注意,ADDS要带有SADC R5, R1, R3 ; 如果使用ADCS,那么结果影响CPSR此外,可以用例如“ADCS R0, R0, R0实现带扩展位的逐位循环移位操作。例如:略SUB指令(

51、减法)语法:SUBS , , 解释:略操作:如果执行条件满足,那么 Rd = Rn-Oprand2 如果 S = 1 且 Rd = R15,那么 如果当前工作模式有SPSR,那么 CPSR = SPSR 否那么,执行结果不可预见如果S =1 但 Rd R15,那么 CPSR的标志位赋值如下: N = Rd31 Z = 1(Rd为0)或0(Rd不为0) C = 结果的借位取反 V = 结果的溢出位(这里是指被减数小于减数的情况)用途:实现数值的减1操作,形如“SUB Ri, Ri, #1;SUBS由于影响CPSR,在循环控制中经常被用到;SUBS也常用于中断(或异常)返回中,形如“SUBS PC

52、, R15, #4。例如:略SBC指令(带借位减法)语法:SBCS , , 解释:略操作:如果执行条件满足,那么 Rd = Rn-Oprand2 NOT(C标志位) 如果 S = 1 且 Rd = R15,那么 如果当前工作模式有SPSR,那么 CPSR = SPSR 否那么,执行结果不可预见 如果S =1 但 Rd R15,那么 CPSR的标志位赋值如下: N = Rd31 Z = 1(Rd为0)或0(Rd不为0) C = 结果的借位取反 V = 结果的溢出位用途:用于实现两个64位数的减法,如果存放器对R1、R0和R3、R2存放64位数,其中R0和R2存放低32位,R1和R3存放高32位,

53、运算结果存入R5、R4中(R4存放低32位,R5存放高32位),那么指令为:SUBS R4, R0, R2SBC R5, R1, R3例如:略RSB指令(逆向减法)语法:RSBS , , 解释:略操作:如果执行条件满足,那么 Rd = Oprand2-Rn 如果 S = 1 且 Rd = R15,那么 如果当前工作模式有SPSR,那么 CPSR = SPSR 否那么,执行结果不可预见 如果S =1 但 Rd R15,那么 CPSR的标志位赋值如下: N = Rd31 Z = 1(Rd为0)或0(Rd不为0) C = 结果的借位取反 V = 结果的溢出位用途:产生负数(二进制补码表示),指令形如

54、“RSB Rd, Rx, #0;产生一个数的2n 1倍,指令形式如“RSB Rd, Rx, Rx, LSL #n。例如:略RSC指令(带借位逆向减法)语法:RSCS , , 解释:略操作:如果执行条件满足,那么 Rd = Oprand2 Rn NOT(C标志位) 如果 S=1 且 Rd = R15,那么 如果当前工作模式有SPSR,那么 CPSR = SPSR 否那么,执行结果不可预见 如果S =1 但 Rd R15,那么 CPSR的标志位赋值如下: N = Rd31 Z = 1(Rd为0)或0(Rd不为0) C = 结果的借位取反 V = 结果的溢出位用途:用于实现64位的减法运算,例如,0

55、减去一个64位的数,存放在R1、R0中(R0存放32位,R1存放高32位),结果存放在R3、R2中(R2存放低32位,R3存放高32位),指令如下:RSBS R2, R0, #0RSB R3, R1, #0例如:略MUL指令(乘法)语法:MULS , , 解释:Rd存放器为目的操作数,存放乘积。Rm存放器为第一个源操作数,存放被乘数。Rs存放器为第二个源操作数,存放乘数。操作:如果执行条件满足,那么 Rd = (Rm * Rs)31:0 如果 S = 1,那么 CPSR的标志位赋值如下: N = Rd31 Z = 1(Rd为0)或0(Rd不为0) C无意义或不受影响 V不受影响用途:实现两个数

56、的乘法操作,由于乘积结果取低32位,因此,对于无符号数和有符号数来说,结果是一样的。这个指令多用于乘积结果不超过32位的乘法操作,实际中要慎用!例如:MUL R3, R2, R1 ; R3 = R2 * R1结果的低32位MLA指令(乘加)语法:MLAS , , , 解释:Rn存放器为第三个源操作数,存储的值被加到Rm*Rs的积上。操作:如果执行条件满足,那么 Rd = (Rm*Rs + Rn)31:0 如果 S=1,那么 CPSR的标志位赋值如下: N=Rd31 Z=1(Rd为0)或0(Rd不为0) C无意义或不受影响 V不受影响用途:实现32位数的乘加运算,Rd不能与Rm相同(ARMv6除

57、外),由于乘法运算和加法运算结果均取低32位,所以,该指令主要用于结果不超过32位的乘加操作,实际中要慎用!例如:略SMULL指令(32位有符号乘法)语法:SMULLS , , , 解释:RdLo存放器为第一个目的操作数,存储乘积的低32位。RdHi存放器为第二个目的操作数,存储乘积的高32位。操作:如果执行条件满足,那么 RdHi = (Rm * Rs)63:32 RdLo = (Rm * Rs)31:0 如果 S = 1,那么 CPSR的标志位赋值如下: N = RdHi31 Z = 1(RdHi和RdLo均为0)或0(RdHi或RdLo不为0) C不受影响 V不受影响用途:该指令是真正意

58、义下的乘法指令。不能使用R15,RdHi和RdLo不能相同。例如:略SMLAL指令(32位有符号乘加)语法:SMLALS , , , 解释:略操作:如果执行条件满足,那么 RdLo = (Rm * Rs)31:0 + RdLo(原先的值)RdHi = (Rm * Rs)63:32 + RdHi + “(Rm * Rs)31:0 + RdLo(原先的值)的进位 如果 S = 1,那么 CPSR的标志位赋值如下: N = RdHi31 Z = 1(RdHi和RdLo均为0)或0(RdHi或RdLo不为0) C不受影响 V不受影响用途:该指令是真正意义上的乘加运算。不用使用R15,RdHi和RdLo

59、不能相同。例如:略UMULL指令(无符号32位乘法指令)语法:UMULLS , , , 解释:略操作:如果执行条件满足,那么 RdHi = (Rm * Rs)63:32 ; 无符号数 RdLo = (Rm * Rs)31:0 如果 S = 1,那么 CPSR的标志位赋值如下: N = RdHi31 Z = 1(RdHi和RdLo均为0)或0(RdHi或RdLo不为0) C不受影响 V不受影响用途:真正意义上的32位无符号乘法运算。不能使用R15,RdHi和RdLo不能相同。例如:略UMLAL指令(无符号乘加)语法:UMLALS , , , 解释:略操作:如果执行条件满足,那么 RdLo = (

60、Rm * Rs)31:0 + RdLo(原先的值)RdHi = (Rm * Rs)63:32 + RdHi + “(Rm * Rs)31:0 + RdLo(原先的值)的进位 如果 S = 1,那么 CPSR的标志位赋值如下: N = RdHi31 Z = 1(RdHi和RdLo均为0)或0(RdHi或RdLo不为0) C不受影响 V不受影响用途:真正意义上32位无符号数的乘加运算。不能使用R15,RdHi和RdLo不能相同。例如:略3.4.3 跳转指令跳转指令有3条,即B、BL和BX,如下所述。B和BL指令(跳转和带连接跳转)语法:BL 解释:L出现在指令中时,指令机器码的L位(第24位)被设

温馨提示

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

评论

0/150

提交评论