ARM开发工具完全支持Thumb指令,应用程序可以灵活的将ARM和Thumb子程序混合编程以便在例程的基础上提高性能或代码密度。在编写Thumb指令时,先要用伪指令CODE16声明(ADS的编译环境下),而且在ARM指令中要使用BX指令跳转到Thumb指令,以切换处理器状态。
采用16位二进制编码,而ARM指令是32位的。
Thumb是压缩指令,先动态解压缩,然后作为标准的ARM指令执行。
由CPSR的T位决定指令流。T置位,执行Thumb指令流,T清0,执行ARM指令流
由ARM模式进入Thumb模式时,是显式或隐式的进入;由Thumb进入ARM模式时,也是显式或隐式的进入。
Thumb指令集没有协处理器指令、信号量指令、乘加指令、64位乘法指令以及访问CPSR和SPSR的指令,而且指令的第2操作数受到限制。
除了分支指令B有条件执行功能外,其他指令均无条件执行。
大多数Thumb数据处理指令采用2地址格式。
在任何时刻,CPSR的第5位(位T)决定了ARM微处理器执行的是ARM指令流还是Thumb指令流。当T置1,则认为是16位的Thumb指令流;当T清0,则认为是32位的ARM指令流。
• 进入Thumb模式
进入Thumb指令模式有两种方法:一种是执行一条交换转移指令BX,另一种方法是利用异常返回,也可以把微处理器从ARM模式转换为Thumb模式。
• 退出Thumb模式
退出Thumb指令模式也有两种方法:一种是执行Thumb指令中的交换转移BX指令可以显式的返回到ARM指令流。另一种是利用异常进入ARM指令流 。
Thumb指令集是ARM指令集的一个子集,并只能对限定的ARM寄存器进行操作。
16位Thumb指令集是从32位ARM指令集提取指令格式的,每条Thumb指令有相同处理器模型所对应的32位ARM指令。
Thumb数据处理指令包括一组高度优化且相当复杂的指令,范围涵盖编译器通常需要的大多数操作。ARM指令支持在单条指令中完成一个操作数的移位及一个ALU操作,但Thumb指令集将移位操作和ALU操作分离为不同的指令。本部分从以下几个方面介绍:
• 数据处理指令的二进制编码
• 数据处理指令的分类
• ARM指令与Thumb指令比较
• 算术运算指令,它又分为以下几类:
• ADD与SUB—低寄存器加法和减法
• ADD—高或低寄存器
• ADD与SUB—SP
• ADD—PC或SP相对偏移
• ADC,SBC和MUL
• 移位和循环移位操作(ASR,LSL,LSR和ROR)
• 比较指令(CMP和CMN)
• 传送和取负指令(MOV,MVN和NEG)
• 测试指令(TST)
ADD与SUB--低寄存器加法和减法
句法:
op Rd,Rn,Rm
op Rd,Rn,#expr3
op Rd,#expr8
用法:
指令中Rd、Rn、Rm必须是低寄存器(R0~R7)。指令更新NZCV标志。
例子:
ADD R3,R1,R5
ADD R9,R2,R6
SUB R0,R4,#5
SUB R4,R5,#201
ADD--高或低寄存器
句法:
ADD Rd,Rm
用法:
Rd←Rd+Rm
Rd和Rm是低寄存器时,更新标志NZCV
例子:
ADD R12,R4
ADD R10,R11
ADD R2,R4
ADD与SUB--SP
句法:
ADD SP,#expr
SUB SP,#expr
用法:
SP←SP+expr
不影响条件标志码
例子:
ADD SP,#312
ADD--PC或SP偏移量
句法:
ADD Rd,Rp,#expr
Rp:SP或PC
用法:
Rd←Rp+#expr
不影响条件标志码
例子:
ADD R6,SP,#64
ADD R2,PC,#980
ADC、SBC和MUL
(带进位位的加法、带进位位的减法、乘法)
句法:
op Rd,Rm
用法:
ADC:Rd←Rd+Rm+C
SBC: Rd ←Rd-Rm-(1-C) 借位
MUL:Rd ←Rd×Rm
限制:Rd和Rm必须是低寄存器(R0~R7)
ADC和SBC影响NZCV
MUL影响NZ
AND、ORR、EOR和BIC(按位逻辑操作)
句法:
op Rd,Rm
用法:
AND逻辑“与”操作
ORR逻辑“或”操作
EOR逻辑“异或”操作
BIC:Rd AND NOT Rm
必须是低寄存器,影响NZ标志
ASR、LSL、LSR和ROR(逻辑和循环位移)
句法:
op Rd,Rs
op Rd,Rm,#expr
Rd、Rs、Rm必须是R0~R7范围内的寄存器
例子:
ASR R3,R5
LSR R0,R2,#6
ROR R2,R7,#2
LSL R9,R1
CMP和CMN(比较和比较负值)
句法:
CMP Rn,#expr
CMP Rn,Rm
CMN Rn,Rm
用法:
只更新条件码标志,不存放结果
CMP:Rn-expr(或Rm)
CMN:Rm+Rn
其中:CMP Rn,Rm指令允许使用高寄存器
例子:
CMP R2,#255 CMP R9,#24
CMN R1,R5 CMN R0,R10
MOV、MVN和NEG(传送、传送非和取负)
句法:
MOV Rd,#expr
MOV Rd,Rm
MVN Rd,Rm
NEG Rd,Rm
用法:
MOV:Rd←#expr(或Rm)
MVN:Rd ←NOT Rm
NEG: Rd ←Rm×(-1)
TST(测试)
句法:
TST Rn,Rm
用法:
Rm AND Rn,丢弃结果,更新条件码标志NZ
Rn、Rm必须在R0~R7范围内
转移指令的二进制编码如下:
转移指令分类如下:
• B-分支指令,Thumb指令集惟一可条件执行的指令。
• BL-带链接的长分支。
• BX-分支指令,并可选择地切换指令集。
• BLX-带链接分支,并可选地交换指令集。
B <cond> <label> ;格式1 目标为Thumb代码
B <label> ;格式2 目标为Thumb代码
BL <label> ;格式3 目标为Thumb代码
BLX <label> ;格式3a 目标为ARM代码
B{L}X Rm ;格式4 目标为ARM或Thumb代码
Thumb的数据存取指令又可以分为:
单寄存器数据存取指令(LDR和STR)
多寄存器数据存取指令 (LDM和STM)
汇编格式如下:
<op> Rd,[Rn,<#off5>] ; = LDR|LDRB|STR|STRB
<op> Rd,[Rn,<#off5>] ; = LDRH| STRH
<op> Rd,[Rn,Rm] ;
<op> =LDR|LDRH|LDRSH|LDRB|LDRSB|STR|STRH|STRB
<op> Rd,[PC,<#off8>]
<op> Rd,[SP,<#off8>] ; = LDR| STR//该两条指令偏移量为8位
LDMIA Rn!,{}
STMIA Rn!,{}
POP {{,PC}}
PUSH {{,LR}}
Thumb软件中断指令
Thumb软件中断指令的二进制编码如下
Thumb软件中断指令的汇编格式如下:
SWI <8位立即数>;<8位立即数>为数字表达式,其取值为0~255范围内的整数。
Thumb断点指令