1TMTHEARCHITECTUREFORTHEDIGITALWORLDARM/Thumb交互工作2TM264v04ARM/ThumbInterworkingwithADS议程交互工作基础交互子程序ARM5T架构扩展3TM364v04ARM/ThumbInterworkingwithADS交互需求Thumb的代码密度和在窄存储器上性能,使得它用在很多有大量C代码的系统上比较理想.然而在很多应用中还是需要在ARM/Thumb两种状态之间切换:在宽的存储器上ARM代码能提供很好的性能在一个应用中,速度关键的部分用ARM代码实现是不错的一些函数只能用ARM指令实现,e.g.存取CPSR(使能/禁止中断和状态的改变)操作协处理器异常处理异常处理时自动进入ARM状态,但系统要求主程序用Thumb代码实现独立的Thumb程序也需要一个ARM的汇编程序头来切换,并调用Thumb程序4TM464v04ARM/ThumbInterworkingwithADS交互指令交互的实现采用跳转交换指令(BX)在Thumb状态BXRn在ARM状态(支持Thumb的内核)BX条件Rn其中Rn可以是(r0~r15)中的任何一个.这将通过拷贝Rn到PC来实现在4GB空间内的一个绝对跳转.其中Rn的Bit-0表明切换到何种状态.5TM564v04ARM/ThumbInterworkingwithADS状态切换ARM/Thumb选择位0-ARMstate1-ThumbstateRn目的地址310131010/1BXPC6TM664v04ARM/ThumbInterworkingwithADS分支交换示例CODE32;StartoffinARMstateADRr0,Into_Thumb+1;Generatebranchtargetaddressandset;bit0,hencearriveinThumbstate.BXr0;BranchexchangetoThumbstate.:CODE16;AssemblesubsequentcodeasThumb.Into_Thumb:ADRr5,Back_to_ARM;Generatebranchtargettowordaligned;address-hencebit0isclear.BXr5;BranchexchangebacktoARMstate.:CODE32;AssemblesubsequentcodeasARM.Back_to_ARM:7TM764v04ARM/ThumbInterworkingwithADS提纲交互基础交互子程序ARM5T架构扩展8TM864v04ARM/ThumbInterworkingwithADS无交互子程序实现一个通常的子程序调用需要如下两步:保存返回地址到寄存器(LR)跳转到对应的子程序地址调用实现通常只需要一个指令:BLfunc2返回实现通常只需从LR恢复PC:MOVpc,lr..BLfunc2..:MOVpc,lrfunc1func2voidfunc1(void){:func2();:}9TM964v04ARM/ThumbInterworkingwithADS混合的ARM/Thumb子程序在使用C/C++写程序时,可以自由的编译为ARM(使用armcc/armcpp)或Thumb(使用tcc/tcpp).需要一些编译方法来解决在一种状态下的函数调用另一种状态下的函数的问题.涉及到的问题:BL不能完成状态切换需要使用BX切换BX不能自动保存返回地址到LR需要其它方法来解决这个问题从子程序返回,要使用BXLR以便返回先前的状态BL在Thumb状态下可能设置了LR的lsb(bit-0)不能使用MOVPC,LR返回,因为不能实现状态切换10TM1064v04ARM/ThumbInterworkingwithADS交互子程序任何包含使用交互调用函数的C模块的编译必须使用-apcs/interwork命令行选项.编译器将使用BX实现函数返回来替代MOVPC,LR.连接器生成一小段代码(‘veneers’)来改变状态当发现交互调用时自动加入目标文件使用armlink-infoveneers可以看到加入的“veneers”的大小,:BL::BX:BXfunc1func2连接程序生成veneer(compiledforinterworking)11TM1164v04ARM/ThumbInterworkingwithADSARM4T架构对交互编译的影响leaffunction使用BX返回.Non_leaffunction将被交互编译:在入口处(调用BL之前)压栈保护返回地址在入口处保护所有函数使用的寄存器使用BX实现返回操作(替代弹出PC).C源代码armcc-apcs/interworktcc-apcs/interworkvoidfunc(void)funcfunc{STMFDsp!,{r4-r11,lr}PUSH{r4-r7,lr}:::sub();BLsubBLsub::::LDMFDsp!,{r4-r11,lr}POP{r4-r7}}BXlrPOP{r3}BXr312TM1264v04ARM/ThumbInterworkingwithADS汇编程序交互工作和Veneers连接程序将会自动加入ARM/Thumb交互veneers到汇编源代码.主调程序需要:使用armasm-apcs/interwork汇编导出自己的符号,e.g.EXPORTThumbSub使用BX实现返回主调程序使用BL指令调用子程序.Note:AREA将包含:AREAThumb,CODE,READONLY,INTERWORK如果如此,armasm将警告:INTERWORKareadirectiveisobsolete.Continuingasif-apcs/interselected.13TM1364v04ARM/ThumbInterworkingwithADS;armasmarm.sAREAArm,CODE,READONLYIMPORTThumbSubENTRYCODE32ARMProgMOVr0,#1BLThumbSub;callThumbsubroutineMOVr0,#0x18LDRr1,=0x20026SWI0x123456;ARMsemihostingSWIEND;armasmthumb.s-apcs/interworkAREAThumb,CODE,READONLYEXPORTThumbSubCODE16ThumbSubMOVr1,#2BXlr;returntocallerEND汇编程序交互工作(1)14TM1464v04ARM/ThumbInterworkingwithADS汇编程序交互工作(2)使用Debugger反汇编代码:ARMProg0x00008080:0xe3a00001:movr0,#10x00008084:0xeb000004:bl0x809c;(ThumbSub+0x4)0x00008088:0xe3a00018:movr0,#0x180x0000808c:0xe59f1000:ldrr1,0x8094;=#0x000200260x00008090:0xef123456:swi0x1234560x00008094:0x00020026:LiteralPoolValueThumbSub0x00008098:0x2102:movr1,#20x0000809a:0x4770:bxlr交互veeners在下一个字的边界0x0000809c:0xe59fc000:ldrr12,0x80a4;=#ThumbSub+0x10x000080a0:0xe12fff1c:bxr120x000080a4:0x00008099:LiteralPoolValue15TM1564v04ARM/ThumbInterworkingwithADSC/汇编使用Veneers交互工作运行在一种状态下的C代码可能调用运行在另一种状态下的汇编程序,反之亦然。这时的veneers由连接程序自动生成。如果主调函数是C函数,编译时使用-apcs/interwork如果主调函数是汇编函数,汇编时使用-apcs/interwork且返回使用BXLR任何使用这些的汇编程序必须符合ATPCS标准,(e.g.函数参数传递使用r0-r3&r12不受保护的)16TM1664v04ARM/ThumbInterworkingwithADS非交互的Thumb代码允许Thumb-Thumb调用交互的Thumb代码非交互的ARM代码允许ARM-ARM调用交互的ARM代码允许非交互的调用交互的不可调用允许ARM/Thumb调用交互调用最好使用交互选项build所有的程序17TM1764v04ARM/ThumbInterworkingwithADS连接交互工作的目标代码为了顺利连接:必须使用统一的APCS标准“built”所有的C/C++/Asm文件.要使用相应的交互工作库连接程序发现任何的不协调就会给出一个错误:InvalidcallfromTHUMBcodeinthumbmain.o(.text)toARMsymbolarm_function.修正编译器/汇编器的配置(e.g.加上-apcs/interwork),然后重新连编。连接时使用‘-infoveneers’来得到增加的veneers的概况,e.g.:AddingATveneer(12bytes)forcallto'_printf’fromThumb_to_ARM.o(.text)AddingTAveneer(12bytes)forcallto'arm_function’fromthumbmain.o(.text)小心非法的间接调用(e.g.函数指针,动态跳转表)–连接器对这种情况在连接时是不会给出警告的。18TM1864v04ARM/ThumbInterworkingwithADS使用CodeWarrior交互工作使用Thumb/ARM交互工作工程模板向ARMDebugRel目标加入ARMC,C++&Asm模块编译C模块使用‘armcc-apcs/interwork’编译C++模块使用‘armcpp-apcs/interwork’编译ASM模块使用‘armasm-32-apcs/interwork’向ThumbDebugRel目标加入ThumbC,C++&Asm模块编译C模块使用‘tcc-apcs/interwork’编译C++模块使用‘tcpp-apcs/interwork’编译ASM模块使用‘armasm-16-apcs/interwork’ARMDebugRel将会被编译连接(部分连接)成ThumbDebugRel的一个子目标19TM1964v04ARM/ThumbInterworkingwithADS提纲交互工作基础交互工作子程序ARM5T架构扩展20TM2064v04ARM/ThumbInterworkingwithADSArchitecture5TInterworkingARM5T架构增加了对交互工作的支持消除了对veneers的需求兼容ARM4T架构的代码改良内容包括新的BLX指令修正了加载PC的动作21TM2164v04ARM/ThumbInterworkingwithADSARM调用Thumb子程序通常切换到Thumb状态32MB分支范围返回地址保存在LR中使用BXLR从子程序返回无条件指令Thumb调用ARM子程序转化为两个16-bit指令偏移范围同Thumb的BL指令i.e.+/-4MB范围返回地址保存在LR(同时设置LSB)BLXoffset:BLXoffset::BXlrARMThumbCPSRTbit=122TM2264v04ARM/ThumbInterworkingwithA