gpt4 book ai didi

assembly - 汇编中的 ARM/Thumb 互操作

转载 作者:行者123 更新时间:2023-12-02 21:57:12 25 4
gpt4 key购买 nike

我正在构建一个 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 加载函数体地址加一并对其执行 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 是如何解码命令的?

最佳答案

您想要的详细信息在《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)被设置,处理器将清除该位,切换到Thumb模式,并执行跳转到新地址的操作。

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

关于assembly - 汇编中的 ARM/Thumb 互操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18262736/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com