Thumb指令集中关于IT指令的使用
- 格式:docx
- 大小:17.35 KB
- 文档页数:2
3.4 Thumb指令集Thumb指令集可以看做ARM指令集的一个子集,其用于支持存储系统数据总线为16位的应用系统。
Thumb指令长度为16位,这样,与32位的ARM指令集相比,有效地节省了系统的存储空间。
但Thumb指令集中的数据处理指令的操作数仍然是32位的,指令寻址地址也是32位的。
在实际应用中,若对系统的性能有较高要求,则选arm指令集和32位的memory;若对系统的功耗有较高要求时,则选Thumb指令集和16位的memory;一般将两者混合使用,根据系统不同部分的不同需求,选用合适的指令,发挥两者的优势。
Thumb指令集由数据处理指令、跳转指令、Load/Store指令和软件中断指令4大类构成。
数据处理指令格式功能MOV Rd,imm_8; Rd=imm_8;Rd为R0~R7,imm_8为8位立即数MOV Rd,Rn; Rd=Rn;Rd、Rn为R0~R15MVN Rd,Rn; Rd=~Rn;Rd、Rn为R0~R7NEG Rd,Rn; Rd=-Rn;Rd、Rn为R0~R7ADD Rd,Rn,imm; Rd=Rn+imm;Rd为R0~R7,Rn为R0~R7或PC或SP;Rn为PC或SP时,imm为10位立即数;否则,imm为3位立即数ADD Rd,Rn,Rm; Rd=Rn+Rm;Rd、Rn、Rm为R0~R7ADD Rd,imm; Rd=Rd+imm;Rd为R0~R7或SPRd为SP时,imm为-508~+508间的4整数倍的数否则,imm为8位立即数ADD Rd,Rn; Rd=Rd+Rn;Rd、Rn为R0~R15ADC Rd,Rn; Rd=Rd+Rn+carry;Rd、Rn为R0~R7,carry为进位标志值SUB Rd,Rn,imm_3; Rd=Rn-imm_3;Rd、Rn为R0~R7,imm_3为3位立即数SUB Rd,Rn,Rm; Rd=Rn-Rm;Rd、Rn、Rm为R0~R7,SUB Rd,imm; Rd=Rd-imm;Rd为R0~R7或SPRd为SP时,imm为-508~+508间的4整数倍的数否则,imm为8位立即数SBC Rd,Rn; Rd=Rd-Rn-!carry;Rd、Rn为R0~R7,carry为进位标志值MUL Rd,Rn; Rd=Rd×Rn;Rd、Rn为R0~R7AND Rd,Rn; Rd=Rd&Rn;Rd、Rn为R0~R7ORR Rd,Rn; Rd=Rd|Rn;Rd、Rn为R0~R7EOR Rd,Rn; Rd=Rd^Rn;Rd、Rn为R0~R7BIC Rd,Rn; Rd=Rd&(~Rn);Rd、Rn为R0~R7ASR Rd,Rn; Rd=Rd算术右移Rn位;Rd、Rn为R0~R7ASR Rd,Rn,imm_5; Rd=Rn算术右移imm_5位;Rd、Rn为R0~R7,imm_5为1~32间的数值LSL Rd,Rn; Rd=Rd逻辑左移Rn位;Rd、Rn为R0~R7 LSL Rd,Rn,imm_5; Rd=Rn逻辑左移imm_5位;Rd、Rn为R0~R7 LSR Rd,Rn; Rd=Rd逻辑右移Rn位;Rd、Rn为R0~R7 LSR Rd,Rn,imm_5; Rd=Rn逻辑右移imm_5位;Rd、Rn为R0~R7 ROR Rd,Rn; Rd=Rd循环右移Rn位;Rd、Rn为R0~R7CMP Rn,Rm; 根据Rn-Rm的值,修改CPSR的状态标志位;Rn、Rm为R0~R7CMP Rn,imm_8; 根据Rn-imm_8的值,修改CPSR的状态标志位;Rn为R0~R7CMN Rn,Rm; 根据Rn+Rm的值,修改CPSR的状态标志位;Rn、Rm为R0~R7TST Rn,Rm; 根据Rn&Rm的值,修改CPSR的状态标志位;Rn、Rm为R0~R7跳转指令格式功能B{cond} label PC=label;若有cond,则label必须在当前指令的-256~+256字节范围内;否则,label必须在当前指令的-2KB~+2KB范围内BL label R14=PC+4,PC=label;label必须在当前指令的-4MB~+4MB范围内BX Rn PC=Rn,且切换处理器状态Load/Store指令格式功能LDR Rd,[Rn,imm]; Rd=地址(Rn+imm)中的字数据;Rd为R0~R7,Rn为R0~R7或SP 或PC;若Rn为PC或SP,imm为5位立即数,否则imm为8位立即数LDR Rd,[Rn,Rm]; Rd=地址(Rn+Rm)中的字数据;Rd、Rn、Rm为R0~R7LDRH Rd,[Rn,imm_5]; Rd=地址(Rn+imm_5)中的无符号半字数据;Rd、Rn为R0~R7,imm_5为5位立即数LDRH Rd,[Rn,Rm]; Rd=地址(Rn+Rm)中的无符号半字数据;Rd,Rn,Rm为R0~R7 LDRB Rd,[Rn,imm_5]; Rd=地址(Rn+imm_5)中的无符号字节数据;Rd、Rn为R0~R7 LDRB Rd,[Rn,Rm]; Rd=地址(Rn+Rm)中的无符号字节数据;Rd,Rn,Rm为R0~R7 LDRSH Rd,[Rn,Rm]; Rd=地址(Rn+Rm)中的有符号半字数据;Rd,Rn,Rm为R0~R7 LDRSB Rd,[Rn,Rm]; Rd=地址(Rn+Rm)中的有符号字节数据;Rd,Rn,Rm为R0~R7 LDR Rd,label; Rd=地址(label)中的字数据;Rd为R0~R7STR Rd,[Rn,imm]; 地址(Rn+imm)处的字数据=Rd;Rd为R0~R7,Rn为R0~R7或SP 或PC;若Rn为PC或SP,imm为5位立即数,否则imm为8位立即数软件中断指令格式功能SWI 8位立即数8位立即数为中断号。
实践-Thumb指令实践指导实践指导1:ARM与Thumb的混合编程1.实验⽬的●使⽤Thumb汇编语⾔,体会ARM与Thumb的区别。
●使⽤伪指令,加深对伪操作的理解。
2.实验设备●硬件:PC机。
●软件:ADS集成开发环境,Windows2000/XP/2003。
3.实验原理ARM与Thumb的混合编程所有的ARM指令都是可以条件执⾏的,⽽Thumb指令仅有⼀条指令(B指令)具备条件执⾏功能。
所以很多应⽤程序需要两者的混合编程,因此存在ARM与Thumb状态之间相互切换,⽽且相互之间的状态切换的开销⼏乎为零。
由于ARM处理器总是从ARM状态开始执⾏,故Thumb指令的执⾏必须由ARM状态转向Thumb状态,通常BX指令完成。
另外在Thumb指令前必须有CODE16伪指令指⽰汇编器以下指令为Thumb指令。
4.实验内容下⾯是⼀段直接进⾏状态切换的代码。
AREA AddReg,CODE,READONL YENTRYCODE32;程序从ARM状态开始ADR R0,ThumbProg+1;跳转到ThumbProg。
这⾥为什么要加1呢?因为BX指令;跳转到指定的地址执⾏程序时,若(BX{cond}Rm)Rm;的位[0]为1,则跳转时⾃动将CPSR中的标志T置位即把;⽬标代码解释为Thunb代码。
BX R0;程序切换到Thumb状态CODE16;CODE16指⽰编译器后⾯为Thumb指令ThumbProg MOV R2,#2MOV R3,#3ADD R2,R2,R3ADR R0,ARMProgBX R0;跳转到ARMProg,程序切换到ARM状态CODE32;CODE32指⽰编译器后⾯为ARM指令ARMProg MOV R4,#4MOV R5,#5ADD R4,R4,R5Stop MOV R0,#0x18;软中断参数设置LDR R1,=0x20026;软中断参数设置SWI0x123456;将CPU的控制权交给调试器END5.操作步骤Step1建⽴⼯程⽂件,输⼊程序代码。
ARM中的条件执⾏指令(IT指令)条件执⾏在之前讨论CPSR寄存器那部分时,我们⼤概提了⼀下条件执⾏这个词。
条件执⾏⽤来控制程序执⾏跳转,或者满⾜条件下的特定指令的执⾏。
相关条件在CPSR寄存器中描述。
寄存器中的⽐特位的变化决定着不同的条件。
⽐如说当我们⽐较两个数是否相同时,我们使⽤的Zero⽐特位(Z=1),因为这种情况下发⽣的运算是a-b=0。
在这种情况下我们就满⾜了EQual的条件。
如果第⼀个数更⼤些,我们就满⾜了更⼤的条件Grater Than或者相反的较⼩Lower Than。
条件缩写都是英⽂⾸字母缩写,⽐如⼩于等于Lower Than(LE),⼤于等于Greater Equal(GE)等。
下⾯列表是各个条件的含义以及其检测的状态位(条件指令都是其英⽂含义的缩写,为了便于记忆不翻译了):image我们使⽤如下代码来实践条件执⾏相加指令:.global mainmain:mov r0, #2 /* 初始化值 */cmp r0, #3 /* 将R0和3相⽐做差,负数产⽣则N位置1 */addlt r0, r0, #1 /* 如果⼩于等于3,则R0加⼀ */cmp r0, #3 /* 将R0和3相⽐做差,零结果产⽣则Z位置⼀,N位置恢复为0 */addlt r0, r0, #1 /* 如果⼩于等于3,则R0加⼀R0 IF it was determined that it is smaller (lower than) number 3 */ bx lr上⾯代码段中的第⼀条CMP指令将N位置⼀同时也就指明了R0⽐3⼩。
之后ADDLT指令在LT条件下执⾏,对应到CPSR寄存器的情况时V与N⽐特位不能相同。
在执⾏第⼆条CMP前,R0=3。
所以第⼆条置了Z位⽽消除了N位。
所以ADDLT不会执⾏R0也不会被修改,最终程序结果是3。
Thumb模式中的条件执⾏在指令集那篇⽂章中我们谈到了不同的指令集,对于Thumb中,其实也有条件执的(Thumb-2中有)。
第4章Thumb 指令集●Thumb 寄存器的使用●ARM-Thumb 交互●其它分支指令●数据处理指令●单寄存器load-store指令●多寄存器load-store 指令●堆栈指令●软件中断指令●总结本章介绍Thumb指令集。
Thumb把32位ARM指令集的一个子集进行编码,成为一个16位的指令集。
在16位外部数据总线宽度下,在ARM处理器上使用Thumb指令的性能要比使用ARM指令的性能更好;而在32位外部数据总线宽度下,使用Thumb指令的性能要比使用ARM指令的性能差。
因此,Thumb指令多用于存储器受限的一些系统中。
相对于ARM指令集,使用Thumb指令集可获得更高的代码密度—一个可执行的程序在内存中所占的空间。
在存储器受限的嵌人式系统中,比如移动电话、PDA等,代码密度是非常重要的;同时,成本压力也会限制存储器的大小、数据宽度和速度。
平均而言,对于同一个程序,使用Thumb指令实现所需的存储空间,要比等效的ARM 指令实现少30%左右,图4. 1显示了对于实现同样的除法运算,使用ARM指令和使用Thumb 指令的汇编代码。
虽然Thumb指令的实现使用了更多的指令,但是它所占的总的存储空间却比较小。
代码密度是Thumb指令集的一个主要优势。
由于Thumb指令集的设计是面向编译器的,而不是针对手写汇编的,所以推荐使用高级语言如C或者C++语言来编程,然后用编译器生成Thumb指令的目标代码。
图4.1 代码密度每一条Thump指令都和一条32位的ARM指令相关。
图4. 2显示了一条Thumb加法指令ADD译码成等效的ARM加法指令,表4. 1给出了在ARMv5TE架构,F的THUMBv2中所有的Thumb指令。
在ThumbISA 中,只有分支指令可被条件执行;同时由于16位空间的限制,桶形移位操作如ASR,LSL,LSR 和RQR,也变成单独的指令。
表4.1 Thumb指令集续表 4.14.1 Thumb 寄存器的使用在Thumb状态下,不能直接访问所有的寄存器,只有寄存器r0~r7是可以被任意访问的,如表4.2所列。
ARM处理器架构的Thumb指令集中关于IT指令的使用
在ARMv6T2以及ARMv7架构扩展了Thumb指令集,其中加入了IT指令,进一步增强了代码的紧凑性。
Thumb中有一个比较有意思的指令——IT,这条指令用于根据指定的条件来执行后面相继的四条指令。
当然,Thumb-2中大部分算术逻辑指令都含有带条件执行的特征,不过Thumb-2是32位的。
如果你需要更紧凑的指令,那么使用Thumb结合ThumbEE来做带条件的指令执行还是不错的选择。
Thumb本身不具备带条件指令执行的特性。
IT指令的描述为:IT{<x>{<y>{<z>}}} <firstcond>
其中,<x>表示第二条指令的条件;<y>表示第三条指令的条件;<z>表示第四条指令的条件。
<firstcond>是条件操作数,表示第一条指令的条件。
<x>、<y>、<z>的标识其实就两种符号——T或E。
T表示Then,表示相应的指令所满足的条件与<firstcond>一致;E表示else,表示相应的指令所满足的条件与<firstcond>完全相反。
因此,对于第一条指令而言,总是为T的,因此不需要在IT中显示给出,它直接对应于<firstcond>的条件。
另外,在IT块中不能再使用IT指令。
即,相继的四条指令中不允许出现IT指令。
下面给出一些示例代码:
//
// hi.s
// test
//
// Created by zenny_chen on 13-5-8.
// Copyright (c) 2013年 zenny_chen. All rights reserved.
//
.text
.align 4
.globl _ThumbEETest, _ThumbEETest2
.thumb
.thumb_func
_ThumbEETest:
eor r1, r1, r1
eor r2, r2, r2
eor r3, r3, r3
eor r12, r12, r12
cmp r1, #0
itete eq
moveq r1, #10
movne r2, #20
moveq r3, #30
movne r12, #50
stmia r0, {r1-r3, r12}
bx lr
.thumb_func
_ThumbEETest2:
mov r1, #1
eor r2, r2, r2
eor r3, r3, r3
eor r12, r12, r12
cmp r1, #0
ittet gt
movgt r1, #10
movgt r2, #20
movle r3, #30 // 这里只能用le(表示小于等于),而不能用lt(表示小于)
movgt r12, #50
stmia r0, {r1-r3, r12}
bx lr。