Thumb指令集之: ARM和Thumb的混合编程
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子
Thumb指令集 ARM 混合编程 Veneer AAPCS 相关文章:
- Thumb指令集之: Thumb指令的特点及实现(08-30)
- Thumb指令集之: Thumb跳转指令(08-30)
- Thumb指令集之: Thumb指令应用(08-30)
- Thumb指令集与ARM指令集的区别(11-21)
- Thumb指令集之: Thumb指令应用(09-30)
- Thumb指令集之: 多寄存器数据传送指令(09-30)