微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM Thumb Thumb-2指令集

ARM Thumb Thumb-2指令集

时间:11-10 来源:互联网 点击:

ral pools可以保存常量并简化访问这些常量的代码,但是,在Harvard架构的处理器中会引起额外的开销。这些开销来自于需要额外的时钟周期来使数据端 口能够对指令流进行访问;这种访问可能是需要把指令流加载的数据缓存中,或者从数据端口直接访问指令存储器。将32位常量分成16比特的两个部分保存在两条指令中,意味着数据直接在指令流中,不再需要通过数据端口来访问了。相对于literal pool方式,这种解决办法可以消除通过数据端口访问指令流的额外开销,进而提高性能,降低功耗。

ARM/Thumb状态切换

在基于ARM 处理器的嵌入式开发中,为了增强系统的灵活性以及提高系统的整体性能经常需要使用16 位的Thumb 指令,所以需要在ARM 和Thumb 状态之间来切换(Interworking)微处理器状态。只要遵循ATPCS调用规则,Thumb子程序和ARM子程序就可以互相调用。首先介绍切换(Interwoking)的基本概念及切换时的子函数调用。

ARM处理器总是从ARM状态开始执行。因而,如果要在调试器中运行Thumb程序,必须为该Thumb程序添加一个ARM程序头,然后再切换到Thumb状态,调用该Thumb程序。

  • Thumb状态 BX Rn
  • ARM状态 BX Rn

其中Rn可以是寄存器R0—R15中的任意一个。指令可以通过将寄存器Rn的内容拷贝到程序计数器PC来完成在4Gbyte地址空间中的绝对跳转,而状态切换是由寄存器Rn的最低位来指定的,如果操作数寄存器的状态位Bit0=0,则进入ARM状态,如果Bit0=1,则进入Thumb状态。在非Interworking函数调用中,调用函数使用BL(Branch with Link)指令,即将返回地址保存在连接寄存器LR中,同时跳转到被调用的子函数程序入口。从子函数返回时执行指令 MOV PC, LR(当然也可能是其他形式的指令,如出栈指令)将LR值直接放入PC中,从而返回到调用函数中的下一条指令的地址,然后继续执行程序。在Interworking函数的调用中,需要在编译时对此函数所在的源程序指定编译开关选项:-apcs / interwork ,即保证程序遵守ARM/Thumb程序混合使用的ATPCS规则。一般来说,这时生成的目标代码会增加2%左右。这样在编译器(compiler)处理这个函数时就会用BX 指令取代MOV PC,LR指令,而且连接器(linker)会自动的产生一小段代码(veneers)来改变处理器状态(ARM/Thumb),对于C/C++程序来说,当编译时如果增加 –apcs/interwork 选项,那就是告诉连接器自动增加一小段代码(veneer)来实现函数调用时ARM/Thumb的状态切换。但是对于使用C程序中的Interwork选项,需要注意的是:

  • 对于一个C /C++源程序中不能同时包含ARM/Thumb指令;
  • 如果C/C++程序间接的调用另一种指令系统下的子程序,编译该程序时需要增加-apcs/interwork选项;

    • 编译用于交互工作的ARM C代码: armcc -apcs/interwork
    • 编译用于交互工作的Thumb C代码:tcc -apcs/interwork
  • 如果调用程序和被调用程序是不同的指令,而被调用程序是Non-Interworking代码,这时不要使用函数指针来调用该被调用程序。

对于汇编程序来说,如果本代码是被调用的函数,则需按照以下步骤处理:

  • 编译时增加-apcs/interwork 选项;ARM汇编armasm -32 -apcs /interwork;Thumb汇编代码:armasm -16 -apcs /interwork;
  • 在入口处保护返回地址(lr)以及寄存器(r0-r7,r8-r12(ARM))
  • 返回前恢复保护的寄存器
  • 用BX来返回;
  • EXPORT本函数名;

如果本代码是调用函数,那就只需要用BL指令来实现子函数的调用即可,也就是正常的处理。当然,用户也可以自己来编写这些状态切换程序,这样执行代码的效率会更高些。对于C/C++程序和汇编程序的相互调用同样需要遵守以上的规则。另外,在实际应用中,如果要在ARM/Thumb状态间来切换程序,最好的办法是所有的函数在编译时都增加 -apcs/interwork选项。关于汇编代码,也可在程序中使用CODE32或CODE16命令明确告知汇编程序下面的代码是ARM代码还是Thumb代码,这样在汇编时则无需使用-32、-16选项;当然也可在单个汇编原文件中混合使用ARM以及Thumb代码,这是需要使用CODE32以及CODE16命令,并且需要注意状态的切换,使用BX Rn,根据Rn的Bit[0]来确定目标是ARM代码还是Thumb代码。如AREA Init,CODE,READONLY CODE32;通知编译器其后的指令为32位的ARM指令。

前面所提到的内容是针对ARM微处理器内核为V4T架构时的切换情况,而对于V5TE架构的ARM内核,除了完全支持V4T架构的代码(具有veneers)外,代码在连接时不再增加veneers,而是使用新的指令BLX(Branch and Link with Exchang)来实现状态切换。这条指令完成完成的任务是:在跳转时将返回的

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

网站地图

Top