ARM / Thumb在程序集中进行交互操作

时间:2013-08-15 22:10:13

标签: assembly arm windows-phone thumb

我正在构建一个Windows Phone项目,其中包含一些部件。我的程序集文件处于ARM模式(CODE32),它尝试跳转到我知道编译为Thumb的C函数。代码如下:

    ldr r12, [pFunc]
    mov pc, r12
pFunc
    dcd My_C_Function

这是奇怪的事情。代码段中pFunc处的值是函数thunk加一的指针。也就是说,设置第0位,就好像跳转目标是Thumb并且跳转指令意味着是BX。但是thunk显然是ARM! thunk加载函数体的地址加1并对其执行BX,正确切换模式。

尝试BX到该地址可能会崩溃,因为这会切换模式并尝试在Thumb模式下执行ARM代码不是一个好主意。试图简单地跳转到该地址(如当前代码所做的那样)也可能会崩溃,因为PC最终会不对齐。

理论上,我可以手动清理第0位然后跳转,但是我的想法会有一些错误。 thunk是由C编译器生成的 - 对吧? C编译器知道thunk是ARM代码。 pFunc下的地址由链接器生成,因为它是跨模块调用。所以低位由链接器放在那里;为什么链接器不知道那些thunk是ARM?

请解释一下?

我现在没有WP8设备,因此无法在真实硬件中尝试。盯着生成的代码是我唯一的调试技术:(

编辑:但是如果这些thunk不是ARM,而是Thumb-2怎么办? Thumb-2支持一些32位命令IIRC。他们的编码是否与ARM模式相同?无论如何,Thumb-2如何解码命令?

3 个答案:

答案 0 :(得分:3)

您需要的详细信息在“ARM体系结构参考手册,ARMv7-A和ARMv7-R版本”的“A2.3.2 ARM核心寄存器上的操作的伪代码详细信息”部分中指定。这是关于写入PC寄存器的相关伪代码(来自上面的手册):

BXWritePC(bits(32) address)
    if CurrentInstrSet() == InstrSet_ThumbEE then
        if address<0> == '1' then
            BranchTo(address<31:1>:'0');  // Remaining in ThumbEE state
        else
            UNPREDICTABLE;
    else
        if address<0> == '1' then
            SelectInstrSet(InstrSet_Thumb);
            BranchTo(address<31:1>:'0');
        elsif address<1> == '0' then
            SelectInstrSet(InstrSet_ARM);
            BranchTo(address);
        else // address<1:0> == '10'
            UNPREDICTABLE;

如果地址(位0)的低位置1,处理器将清除该位,切换到Thumb模式,并跳转到新地址。

此行为适用于ARMv7及更高版本(即适用于所有Windows Phone设备,但不适用于所有Android / iOS设备)。

答案 1 :(得分:2)

你手上可能有一个有效/真实的问题。 Afaik Windows Phone环境为required to be Thumb-2 only,因此您使用的链接器可能无法处理对ARM模式的调用。在混合程序集和C时,请参阅相同的链接以了解一些注意事项。

如果这是一个Linux / ELF问题,我会以不同的方式回答;

  
    

pFunc下的地址由链接器生成,因为它是跨模块调用。所以低位由链接器放在那里。

  

pFunccompiler生成,linker将在您构建可加载映像时修复它,该映像已经完全解析为静态重新调用调用。所有可移植对象文件都应该包含一个关于函数模式的表,以便以后链接器可以处理它们并相应地重新定位和更新调用序列。

有关如何通过ELF文件完成此操作,请参阅ELF for the ARM Architecture - 4.6 Relocation

答案 2 :(得分:2)

反汇编程序(特别是IDA Demo)通过将几个命令合并为一行来误导我。它从mov序列中产生了一条mov-orr-orr行,用于为寄存器分配一个完整的32位常量。毕竟雷通是拇指。链接器按设计工作。

IDA非常棒。我在脑海中知道关于ARM的这种特殊行为,但这一次它滑落了。

我对那些试图提供帮助的人表示不满,感谢和赞成。