Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 装配中的臂/拇指交互工作_Assembly_Arm_Windows Phone_Thumb - Fatal编程技术网

Assembly 装配中的臂/拇指交互工作

Assembly 装配中的臂/拇指交互工作,assembly,arm,windows-phone,thumb,Assembly,Arm,Windows Phone,Thumb,我正在构建一个Windows Phone项目,其中一些部分正在组装中。我的汇编文件处于ARM模式(CODE32),它试图跳转到我知道编译为Thumb的C函数。代码如下所示: ldr r12, [pFunc] mov pc, r12 pFunc dcd My_C_Function 奇怪的是。代码段中pFunc处的值是指向函数thunk加1的指针。也就是说,设置第0位,就好像跳转目标是Thumb,跳转指令是BX。但那一击显然是手臂!thunk加载函数体的地址加上一,并对其执

我正在构建一个Windows Phone项目,其中一些部分正在组装中。我的汇编文件处于ARM模式(
CODE32
),它试图跳转到我知道编译为Thumb的C函数。代码如下所示:

    ldr r12, [pFunc]
    mov pc, r12
pFunc
    dcd My_C_Function
奇怪的是。代码段中
pFunc
处的值是指向函数thunk加1的指针。也就是说,设置第0位,就好像跳转目标是Thumb,跳转指令是BX。但那一击显然是手臂!thunk加载函数体的地址加上一,并对其执行BX,正确切换模式

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

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

有什么解释吗

我现在没有WP8设备,所以我不能在真正的硬件中尝试它。我所拥有的唯一调试技术就是盯着生成的代码:(


编辑:但如果这些Thunk不是ARM,而是Thumb-2呢?Thumb-2支持一些32位命令IIRC。它们的编码是否与ARM模式中的相同?Thumb-2如何解码命令?

您想要的详细信息在“ARM架构参考手册,ARMv7-A和ARMv7-R版本”。以下是有关写入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;
BXWritePC(位(32)地址)
如果CurrentInstrSet()==InstrSet_ThumbEE,则
如果地址==“1”,则
BranchTo(地址:'0');//仍处于ThumbEE状态
其他的
不可预知的
其他的
如果地址==“1”,则
选择InstrSet(InstrSet_拇指);
BranchTo(地址:“0”);
elsif地址=='0'然后
选择InstrSet(InstrSet_ARM);
布兰奇托(地址);
else//address==“10”
不可预知的
如果设置了地址的低位(位0),处理器将清除该位,切换到Thumb模式,并跳转到新地址


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

您可能手头有一个有效的/实际的问题。如果Windows Phone环境是,那么您使用的链接器可能无法处理到ARM模式的调用。混合汇编和C时,请参阅同一链接以了解一些注意事项

如果这是一个Linux/ELF问题,我会给出不同的回答

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

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

有关如何通过ELF文件执行此操作的信息,请参见。

反汇编程序(特别是IDA演示)通过将多个命令合并成一行误导了我。它从一个
mov orr orr
序列中生成了一个
mov
行,该序列旨在为寄存器分配一个完整的32位常量。thunk毕竟是拇指。链接器按设计工作

艾达在其他方面也很棒。我在脑海里就知道关于手臂的这种特殊行为,但这次它滑倒了


我的不好,谢谢并向所有试图提供帮助的人表示感谢。

如果您在汇编中正确定义了所有标签(使用gnu assembler,您使用.thumb_func处理thumb标签,不知道如何使用其他工具链),C应该自行处理。从那里,汇编器、编译器和链接器将根据目的地将bx处理为偶数或奇数地址。汇编器是MASM的ARM风格。我将检查是否可以相应地装饰标签。但是,从理论上讲,我可能不知道其他对象文件的模式。什么如果它们是第三方对象?我希望链接器对此很聪明。这是我的观点,我希望链接器对此很聪明,如果你有反汇编程序,请使用反汇编程序检查并确保工具正确。这正是我正在做的,缺少设备。这证实了我的怀疑,即代码太离谱了,但没有解释原因链接器会写一个指向军队目的地的拇指指针吗?它就是链接器,对吗?你问题中被误解的部分是
试图简单地跳转到那个地址(就像当前代码那样)也可能会崩溃,因为PC最终将无法对齐。
。正如上面的伪代码所建议的那样,处理器将自动清除最低位,并仅将其用作切换到Thumb模式的指示。IDK哪个工具负责在Windows Phone上设置函数指针中的位0,它可以是静态链接器(导出的Thumb函数的地址将设置位0)或加载程序(它可以使用有关Thumb函数的metainfo在导入表中的指针中设置位0)。实际上,差别不大。我查看的是文件中的DLL代码,而不是执行代码。加载程序还没有机会:)相关引号:汇编程序设置代码段中符号的每个字的LSB,因为它