微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Thumb指令集之: ARM和Thumb的混合编程

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

时间:08-30 来源:3721RD 点击:

11.10 ARM和Thumb的混合编程

11.10.1 互交工作基础

Thumb以其较高的代码密度和在窄存储器上的性能,使得它在很多系统中得到广泛应用。但在很多情况下,还是不得不使用ARM指令,这是因为:

① ARM代码比Thumb代码有更快的执行速度;

② ARM处理器的一些特定功能必须由ARM指令实现,其中包括PSR指令、协处理器指令;

③ 异常发生时,处理器自动进入ARM状态,如果异常处理程序需要使用Thumb指令也必须通用一个ARM程序头(ARM assembler header)。

基于以上原因,即使程序需要由Thumb代码实现,也必须通过ARM-Thumb互交(ARM-Thumb interworking)进入Thumb状态。

ARM-Thumb互交是指对汇编语言和C/C++语言的ARM和Thumb代码进行连接的方法,它进行两种状态(ARM和Thumb状态)间的切换。在进行这种切换时,有时需使用额外的代码,这些代码被称为Veneer。AAPCS定义了ARM和Thumb过程调用的标准。

从一个ARM例程调用一个Thumb例程,内核必须进行状态切换。状态的变化由CPSR的T位来显示。在跳转到一个例程时BX指令可用于ARM和Thumb状态切换,具体用法如下。

在Thumb状态调用ARM例程时,采用:

BX Rn;

在ARM状态调用Thumb例程时,采用:

BX{cond} Rn;

其中,Rn可以是r0~r15中的任意寄存器。

这种带状态切换的跳转指令BX,将寄存器Rn的内容拷贝到程序计数器寄存器PC,因此可以实现4G空间的跳转。指令根据寄存器Rn的bit[0]来决定处理器是否进行状态切换,详细内容参见ARM指令一节。

下面是一段ARM程序,该程序调用虚拟的SWI_writeC子程序从存储器的固定地址取出字符串"hello world"并输出。

AREA Hello,CODE,READONLY

SWI_WriteC EQU &0 ;软中断调用参数

SWI_Exit EQU &11 ;程序退出软中断调用参数

ENTRY

START ADR r1,TEXT ;取字符串地址

LOOP LDRB r0,[r1],#1 ;取下一字节内容

CMP r0,#0 ;判断是否为字符串尾

SWINE SWI_WriteC ;软中断调用打印字符

BEN LOOP ;循环

SWI SWI_Exit ;软中断调用退出程序执行

TEXT = "Hello World",&0a,&0d,0

END

下面的代码将上面的ARM代码转换成等价的Thumb代码。

AREA HelloW_Thumb,CODE,READONLY

SWI_WriteC EQU &0 ;软中断调用参数

SWI_Exit EQU &11 ;程序退出软中断调用参数

ENTRY ;程序入口点

CODE32 进入ARM状态

ADR r0, START+1 ;取得Thumb代码入口地址

BX r0 ;进入Thumb代码

CODE16 ;Thumb代码入口点

START ADR r1, TEXT ;r1 -> "Hello World"

LOOP LDRB r0, [r1] ;取下一字节内容

ADD r1, r1, #1 ;地址指针加1 **T

CMP r0, #0 ;判断是否为字符串尾

BEQ DONE ;完成? **T

SWI SWI_WriteC ;如果不是字符串尾

B LOOP ;继续循环

DONE SWI SWI_Exit ;程序退出

align ;字对齐

TEXT DATA

"Hello World",&0a,&0d,&00

END

上例中,ARM代码到Thumb代码转换过程中新增加的指令用"**T"标注。

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

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

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

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

③ 在ARM和Thumb混合编程时,常使用align伪操作保证内存地址对齐。

11.10.2 互交子程序

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

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

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

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

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

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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top