资料介绍
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子程序。
③ 间接调用ARM子程序的Thumb子程序。
④ 间接调用Thumb子程序的ARM子程序。
如果在程序连接阶段,连接器发现ARM子程序和Thumb子程序间存在相互调用,而源文件在编译时没有使用--apcs/interwork选项,则连接器将报告以下错误。
Error: L6239E: Cannot call ARM symbol ‘arm_function’ in non-interworking object
armsub.o from THUMB code in thumbmain.o(.text)
其中,“arm_function”为需要进行状态切换的子程序名。
在这种情况下,用户必须使用--apcs/interwork选项重新对源文件进行编译。
但在下面两种情况下,不必指定--apcs/interwork选项。
① 在Thumb状态下,发生异常中断时,处理器自动切换到ARM状态,这时不需要添加状态切换代码。
② 当异常发生在Thumb状态时,从异常返回不需要添加状态切换的Veneer代码。
1.使用汇编语言实现互交
对于汇编程序来说,可以有两种方法来实现程序状态的切换。第一种方法是利用连接器提供的交互子程序Veneer来实现程序状态的切换,这时用户可以使用指令BL来调用子程序;另一种方法是用户自己编写状态切换的程序。
在ARMv4版本及其以前的版本中,可以使用BX指令实现程序状态的切换。
从ARMv5版本开始,下面的指令也可以用来实现程序的状态切换。
· BX(Branch and eXchange)
· BLX、LDR、LDM和POP
下面的两个伪操作用来区分源程序中的ARM代码和Thumb代码。
· CODE16
· CODE32
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子程序。
③ 间接调用ARM子程序的Thumb子程序。
④ 间接调用Thumb子程序的ARM子程序。
如果在程序连接阶段,连接器发现ARM子程序和Thumb子程序间存在相互调用,而源文件在编译时没有使用--apcs/interwork选项,则连接器将报告以下错误。
Error: L6239E: Cannot call ARM symbol ‘arm_function’ in non-interworking object
armsub.o from THUMB code in thumbmain.o(.text)
其中,“arm_function”为需要进行状态切换的子程序名。
在这种情况下,用户必须使用--apcs/interwork选项重新对源文件进行编译。
但在下面两种情况下,不必指定--apcs/interwork选项。
① 在Thumb状态下,发生异常中断时,处理器自动切换到ARM状态,这时不需要添加状态切换代码。
② 当异常发生在Thumb状态时,从异常返回不需要添加状态切换的Veneer代码。
1.使用汇编语言实现互交
对于汇编程序来说,可以有两种方法来实现程序状态的切换。第一种方法是利用连接器提供的交互子程序Veneer来实现程序状态的切换,这时用户可以使用指令BL来调用子程序;另一种方法是用户自己编写状态切换的程序。
在ARMv4版本及其以前的版本中,可以使用BX指令实现程序状态的切换。
从ARMv5版本开始,下面的指令也可以用来实现程序的状态切换。
· BX(Branch and eXchange)
· BLX、LDR、LDM和POP
下面的两个伪操作用来区分源程序中的ARM代码和Thumb代码。
· CODE16
· CODE32
下载该资料的人也在下载
下载该资料的人还在阅读
更多 >
- ARM处理器的寻址方式和指令集介绍 33次下载
- ARM和Thumb-2的指令集快速参考卡 21次下载
- Thumb指令集之Thumb跳转指令 1次下载
- Thumb数据处理指令 0次下载
- Thumb指令集之Thumb编程模型 0次下载
- Thumb指令的特点及实现 0次下载
- Thumb指令集之多寄存器数据传送指令解析 0次下载
- Thumb指令集之Thumb指令应用 0次下载
- Thumb指令集之异常中断产生指令解析 0次下载
- ARM和Thumb-2指令集快速参考卡 20次下载
- arm7指令集
- ARM指令集详解
- ARM/THUMB指令系统
- ARM/THUMB微处理器结构及指令系统
- arm7tdmi(s)指令系统
- 现代处理器的主要指令集架构 3025次阅读
- 讲讲ARM指令集格式以及常用的ARM汇编指令 2543次阅读
- 混合编程中的模块命名与管理 835次阅读
- ARM架构常用术语解析 2407次阅读
- Thumb指令、Thumb-2指令、Thumb-2EE 指令区别是什么 1.3w次阅读
- 嵌入式处理器的体系架构与内核 3202次阅读
- 详解CPU功耗的方法与技巧 5820次阅读
- PLC编程入门基础技术知识(plc原理和指令集及编程规则) 6.8w次阅读
- Cortex-M系列处理器指令集_指令集特性比较总结 7689次阅读
- 基于μC/OSII和ARM7 中断机制的IRQ中断响应机制改进及优化解决方案 1993次阅读
- risc指令集是什么_有哪些 1.9w次阅读
- mips指令集指的是什么 1.2w次阅读
- mips汇编指令集功能的介绍 2.2w次阅读
- esp8266 at指令集详解 14.1w次阅读
- thumb指令集是什么_thumb指令集与arm指令集的区别 1.8w次阅读
下载排行
本周
- 1TC358743XBG评估板参考手册
- 1.36 MB | 330次下载 | 免费
- 2开关电源基础知识
- 5.73 MB | 6次下载 | 免费
- 3100W短波放大电路图
- 0.05 MB | 4次下载 | 3 积分
- 4嵌入式linux-聊天程序设计
- 0.60 MB | 3次下载 | 免费
- 5基于FPGA的光纤通信系统的设计与实现
- 0.61 MB | 2次下载 | 免费
- 6基于FPGA的C8051F单片机开发板设计
- 0.70 MB | 2次下载 | 免费
- 751单片机窗帘控制器仿真程序
- 1.93 MB | 2次下载 | 免费
- 8基于51单片机的RGB调色灯程序仿真
- 0.86 MB | 2次下载 | 免费
本月
- 1OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 2555集成电路应用800例(新编版)
- 0.00 MB | 33564次下载 | 免费
- 3接口电路图大全
- 未知 | 30323次下载 | 免费
- 4开关电源设计实例指南
- 未知 | 21548次下载 | 免费
- 5电气工程师手册免费下载(新编第二版pdf电子书)
- 0.00 MB | 15349次下载 | 免费
- 6数字电路基础pdf(下载)
- 未知 | 13750次下载 | 免费
- 7电子制作实例集锦 下载
- 未知 | 8113次下载 | 免费
- 8《LED驱动电路设计》 温德尔著
- 0.00 MB | 6653次下载 | 免费
总榜
- 1matlab软件下载入口
- 未知 | 935054次下载 | 免费
- 2protel99se软件下载(可英文版转中文版)
- 78.1 MB | 537796次下载 | 免费
- 3MATLAB 7.1 下载 (含软件介绍)
- 未知 | 420026次下载 | 免费
- 4OrCAD10.5下载OrCAD10.5中文版软件
- 0.00 MB | 234315次下载 | 免费
- 5Altium DXP2002下载入口
- 未知 | 233046次下载 | 免费
- 6电路仿真软件multisim 10.0免费下载
- 340992 | 191185次下载 | 免费
- 7十天学会AVR单片机与C语言视频教程 下载
- 158M | 183278次下载 | 免费
- 8proe5.0野火版下载(中文版免费下载)
- 未知 | 138040次下载 | 免费
评论
查看更多