若Rn在寄存器列表中: 对于LDMIA指令,Rn的最终值是加载的值,而不是增加后的地址; 对于STMIA指令,若Rn是寄存器列表中的最低数字的寄存器,则Rn存储的值为Rn在初值,其它 情况不可预知。 应用示例: LDMIA R0!,{R2-R7} ;加载R0指向的地址上的多字数据,保存到R2~R7中, R0的值更新。 STMIA R1!,{R2-R7} ;将R2~R7的数据存储到R1指向的地址上,R1值更新 Thumb数据处理指令 Thumb数据处理指令涵盖了编译器需要的大多数操作。大部分的Thumb数据处理指令采用2地址格式,不能在单指令中同时完成一个操作数的移位及一个ALU操作。所以数据处理操作比ARM状态的更少,并且访问寄存器R8~R15受到限制。数据处理指令分为两类: (1)数据传送指令;(2)算术逻辑运算指令 Thumb数据处理指令——数据传送指令 |
数据传送指令——MOV |
注意: “MOV Rd,#expr”指令会更新N和Z标志,对标志C和V无影响。 “MOV Rd,Rm”指令,若Rd或Rm是高寄存器(R8~R15),则标志不受影响,若Rd或Rm都是低 寄存器(R0~R7),则更新标志N和Z,且清除标志C和V。 应用示例: MOV R1,#0x10 ; R1=0x10 MOV R0,R8 ; R0=R8 MOV PC,LR ; PC=LR,子程序返回 数据传送指令——MVN MVN指令将寄存器Rm按位取反后传送到目标寄存器Rd中。指令的执行会更新N和Z标志,对标志C和V无影响。其指令格式如下: |
应用示例: MVN R1,R2 ; 将R2取反,结果存于R1 数据传送指令——NEG NEG指令将寄存器Rm乘以-1后传送到目标寄存器Rd中。指令会更新N、Z、C和V标志。其指令格式如下: |
应用示例: NEG R1,R0 ; R1=-R0 Thumb数据处理指令——算术逻辑运算指令 算术逻辑指令包括以下几类:(1)算术指令(2)逻辑运算指令(3)移位指令(4)比较指令。 算术运算指令——ADD ADD指令将两个数据相加,结果保存到Rd寄存器中。 |
应用示例: ADD R1,R1,R0 ; R1=R0+R1 ADD R1,R1,#7 ; R1=R1+7 ADD R1,#200 ; R1=R1+200 |
应用示例: ADD R1,R10 ; R1=R1+R10 |
应用示例: ADD SP,#-500 ;SP=SP-500 算术运算指令——SUB SUB指令将两个数据相减,结果保存到Rd寄存器中。 |
应用示例: SUB R1,R1,R0 ; R1=R1-R0 SUB R1,R1,#7 ; R1=R1-7 SUB R1,#200 ; R1=R1-200 |
应用示例: SUB SP,#-380 ;SP=SP-380 算术运算指令——ADC ADC指令将Rm的值相加,再加上CPSR中的C条件标志位,结果保存到Rd寄存器。 |
应用示例(64位加法): ADD R0,R2 ADC R1,R3 ;(R1、R2)=(R1、R0)+(R3、R2) 算术运算指令——SBC SBC指令用寄存器Rd减去Rm,再减去CPSR中的C条件标志位的非,结果保存到Rd寄存器。 |
应用示例(64位减法): SUB R0,R2 SBC R1,R3 ;(R1、R2)=(R1、R0)-(R3、R2) 算术运算指令——MUL MUL乘法指令用寄存器Rd乘以Rm,结果保存到Rd寄存器。 |
应用示例(64位减法): MUL R0,R1 ;R0=R0×R1 逻辑运算指令——AND AND指令将寄存器Rd的值与寄存器Rm的值按位作逻辑“与”操作,结果保存到Rd寄存器中。 |
应用示例: MOV R1,#0x0F AND R0,R1 ; R0=R0 & R1,清零R0高24位 逻辑运算指令——ORR ORR指令将寄存器Rd的值与寄存器Rn的值按位作逻辑“或”操作,结果保存到Rd寄存器中。 |
应用示例: MOV R1,#0x0F ORR R0,R1 ; R0=R0 | R1,置位R0低4位 逻辑运算指令——EOREOR指令将寄存器Rd的值与寄存器Rn的值按位作逻辑“异或”操作,结果保存到Rd寄存器中。 |
应用示例: MOV R1,#0x0F EOR R0,R1 ; R0=R0 ^ R1,取反R0低4位 逻辑运算指令——BIC BIC指令将寄存器Rd的值与寄存器Rm的值的反码作逻辑“与”操作,结果保存到Rd寄存器中。 |
应用示例: MOV R1,#0x02 BIC R0,R1 ; 清零R0的第2位,其它位不变 移位指令——ASR ASR指令将数据算术右移,将符号位拷贝到左侧空出的位,移位结果保存到Rd寄存器中。 |
若移位位数为32,则Rd清零,最后移出的位保留在标志C中;若移位位数大于32,则Rd和标志C均被清零;若移位位数为0,则不影响C标志。 应用示例: ASR R1,R2 ASR R3,R1,#2 移位指令——LSL LSL指令将数据逻辑左移,空位清零,移位结果保存到Rd寄存器中。 |
若移位位数为32,则Rd清零,最后移出的位保留在标志C中;若移位位数大于32,则Rd和标志C均被清零;若移位位数为0,则不影响C标志。 应用示例: LSL R6,R7 LSL R1,R6,#2 移位指令——LSR LSR指令将数据逻辑右移,空位清零,移位结果保存到Rd寄存器中。 |
若移位位数为32,则Rd清零,最后移出的位保留在标志C中;若移位位数大于32,则Rd和标志C均被清零;若移位位数为0,则不影响C标志。 应用示例: LSR R3,R0 LSR R5,R2,#2 移位指令——ROR ROR指令将数据循环右移,寄存器右侧移出的位放入左侧空出的位上,移位结果保存到Rd寄存器中。 |
应用示例: ROR R3,R0 比较指令——CMP CMP指令使用寄存器Rn的值减去第二个操作数的值,根据操作的结果更新CPSR中的N、Z、C和V标志位。 |
应用示例: CMP R1,#10 ;R1与10比较,设置相关标志位 CMP R1,R2 ;R1与R2比较,设置相关标志位 比较指令——CMN CMN指令使用寄存器Rn的值加上寄存器Rm的值,根据操作的结果更新CPSR中的N、Z、C和V标志位。 |
应用示例: CMN R0,R2 ;R0与-R2比较,设置相关标志位 比较指令——TST TST指令将寄存器Rn的值与寄存器Rm的值按位作逻辑“与”操作,根据操作的结果更新CPSR中的N、Z、C和V标志位。 |
应用示例: MOV R0,#0x01 TST R1,R0 ;判断R1的最低位是否为0 Thumb分支指令 |
分支指令——B B指令跳转到指定的地址执行程序,它是Thumb指令集中的唯一有条件执行指令。如果使用了条件执行,那么跳转范围在-252~+256字节内。如果没有使用条件执行,那么跳转范围在±2K内。 |
应用示例:
B WAITB ;WAITB标号在当前指令的±2K范围内 BEQ LOOP1 ;LOOP1标号在当前指令的-252~+256范围内 分支指令——BL BL指令在跳转到指定地址执行程序前,将下一条指令的地址拷贝到R14链接寄存器中。 |
注意:由于BL指令通常需要大的地址范围,很难用16位指令格式实现,为此,Thumb采用两条这样的指令组合成22位半字偏移(符号扩展为32位),使指令转移范围为±4MB。 |
分支指令——BX BX指令是带状态切换的分支指令,跳转地址由Rm指定,同时根据Rm的最低位的值切换处理器状态,当最低两位均为0时,切换到ARM状态。 |
应用示例: ADR R0,ArmFun ;将ARM程序段地址存入R0 BX R0 ;跳至R0指定的地址,并切换到ARM状态 Thumb杂项指令——SWI SWI指令用于产生软中断,从而实现从用户模式变换到管理模式,CPSR保存到管理模式的SPSR中,同时程序跳转到SWI向量。在系统模式下也可以使用SWI指令,处理器同样能切换到管理模式。(参数传递的方法参看ARM指令SWI的使用) |
应用示例: SWI 1 ;软中断,中断立即数为0 SWI 0x55 ;软中断,中断立即数为0x55 Thumb伪指令——ADR ADR伪指令将基于PC相对偏移的地址值读取到寄存器中。 |
Thumb伪指令——LDR LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。详细说明参看ARM伪指令部分。 |
Thumb伪指令——NOP NOP伪指令在汇编时将被替换成一条Thumb空操作的指令。比如可能为“MOV R0,R0”指令。NOP伪指令可用于延时操作。 |
电工学习网 ( )
GMT+8, 2021-12-6 20:44