新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > Thumb指令集之: ARM和Thumb的混合编程

Thumb指令集之: ARM和Thumb的混合编程

作者:时间:2013-09-30来源:网络收藏

本文引用地址:http://www.eepw.com.cn/article/257035.htm

在实现代码和Thumb代码转换时,大部分的指令有等价的Thumb指令,只有少数指令没有。如加载字节指令(LDR)不支持自动变址,软中断指令不能条件执行。

在编写Thumb代码时要注意以下几点。

①汇编器需要知道什么时候产生代码、什么时候产生Thumb代码,程序中使用CODE32和CODE16伪操作提供给编译器这些信息。

②由于处理器上电执行是在ARM状态下完成的,所以要使用Thumb指令必须由ARM指令调用Thumb指令,这一过程是通过“BXLR”指令来实现的。需要注意的是,在使用“BXLR”指令前,要对寄存器LR做正确的初始化。

③在ARM和Thumb时,常使用ALIGN伪操作保证内存地址对齐。

11.10.2互交子程序

编写ARM/Thumb互交代码时,下面两点需要注意。

①对于C/C++子程序而言,只要在编译时指定--apcs/interwork选项,汇编器会生成合适的返回代码,使得程序返回到和调用程序相同的状态。

②在汇编语言子程序中,用户必须自己编写相应的返回代码,使得程序返回到和调用程序相同的状态。

如果目标代码包含以下内容,应该在编译或汇编时使用--apcs/interwork选项使处理器能够在ARM和Thumb代码间进行正确的切换,这种情况包含以下4种。

①需要返回到ARM状态的Thumb子程序。

②需要返回到Thumb状态的ARM子程序。

③间接调用ARM子程序的Thumb子程序。

④间接调用Thumb子程序的ARM子程序。

如果在程序连接阶段,连接器发现ARM子程序和Thumb子程序间存在相互调用,而源文件在编译时没有使用--apcs/interwork选项,则连接器将报告以下错误。

Error:L6239E:CannotcallARMsymbol'arm_function'innon-interworkingobject

armsub.ofromTHUMBcodeinthumbmain.o(.text)

其中,“arm_function”为需要进行状态切换的子程序名。

在这种情况下,用户必须使用--apcs/interwork选项重新对源文件进行编译。

但在下面两种情况下,不必指定--apcs/interwork选项。

①在Thumb状态下,发生异常中断时,处理器自动切换到ARM状态,这时不需要添加状态切换代码。

②当异常发生在Thumb状态时,从异常返回不需要添加状态切换的代码。

1.使用汇编语言实现互交

对于汇编程序来说,可以有两种方法来实现程序状态的切换。第一种方法是利用连接器提供的交互子程序来实现程序状态的切换,这时用户可以使用指令BL来调用子程序;另一种方法是用户自己编写状态切换的程序。

在ARMv4版本及其以前的版本中,可以使用BX指令实现程序状态的切换。

从ARMv5版本开始,下面的指令也可以用来实现程序的状态切换。

·BX(BranchandeXchange)

·BLX、LDR、LDM和POP

下面的两个伪操作用来区分源程序中的ARM代码和Thumb代码。

·CODE16

·CODE32

下面简单介绍用于状态切换的指令和伪操作,更详细的信息请分别参见相关章节。

(1)BX指令

ARM状态下的BX指令,使程序跳转到指令中指定的参数Rm指定的地址执行程序,Rm的第0位拷贝到CPSR中T位,位[31∶1]移入PC。若Rm的bit[0]为1,则跳转时自动将CPSR中的标志位T置位,即把目标地址的代码解释为Thumb代码;若Rm的位bit[0]为0,则跳转时自动将CPSR中的标志位T复位,即把目标地址代码解释为ARM代码。指令的语法格式如下。

BX{cond>}Rm>

①cond>

为指令编码中的条件域。它指示指令在什么条件下执行。当cond>忽略时,指令为无条件执行(cond=AL(Alway))。

②Rm>

包含跳转指令的目标地址。如果Rm的bit[0]=0,目标地址处指令为ARM指令;如果Rm的bit[0]=1,目标地址处指令为Thumb指令。

指令操作的伪代码。

指令操作的伪代码如下面程序段所示。

IfconditionPassed{cond}then

TFlag=Rm[0]

PC=RmAND0xfffffffe

Thumb状态下的BX指令,用于ARM和Thumb代码间的相互调用。

指令的语法格式。

BXRm>

其中Rm>为目标地址寄存器,包含程序的跳转地址。BX指令的目标地址寄存器可以是r0~r15中的任意寄存器。

注意

如果Rm[1:0]=0b10,不满足ARM指令的内存对齐方式。指令的执行结果不可预知。如果该指令使用r15作为目标寄存器,其操作方式和使用其他寄存器相同。

c++相关文章:c++教程




评论


相关推荐

技术专区

关闭