从arm程序集调用c函数时,堆地址发生了移位

Address of heap shifted while calling c function from arm assembly?

本文关键字:地址 发生了 程序集 arm 调用 函数      更新时间:2023-10-16

下面是我的代码:

test.cpp
class Message
{
public:
    long long msgid;
    char* msgStr;
};
int foo(Message* msg)
{
    // TODO
    // print: msg->msgid, msg->msgStr
}
int main()
{
     char buf[20] = "Hello";
     Message msg = new Message;
     msg->msgid = 0x10;
     msg->msgStr = buf;
     foo(msg);
     call_from_arm((void*)&foo, (void*)msg);
     foo(msg);
     return 0;
}

test.S
call_from_arm:
@r0 = ptrFunc
@r1 = obj
STMFD   r13!, {r4-r11,r14}
MOV r8, r0              @r8 = ptrFunc
MOV r0, r1              @r0 = r1
BLX r8              @call ptrFunc
LDMFD   r13!, {r4-r11,pc}

当应用程序运行时,我发现call_from_arm传递给foo的参数是正确的(msg的地址),但是Message实例包含错误的值,就好像堆上的内容被偏移了。

这个应用程序的输出看起来像:

msgid : 10, msgStr : Hello
msgid : (wrong value), msgStr : (wrong value, app may crash here)
msgid : 10, msgStr : Hello
这个问题已经困扰我好几天了。请帮帮我。由于

如果我把Message类改成

class Message
{
    char* msgStr;
}

我可以打印字符串"Hello"的正确值,所以我认为问题可能是字节对齐。long long是关键点。但我还是不知道为什么。


I have solved this problem. AAPCS requires 8 bytes-align. 
My old version code store r4-r11 & lr into stack, whitch is not 8 bytes-aligned.

请按以下方式更改call_from_arm

 call_from_arm:
 @r0 = ptrFunc
 @r1 = obj
 MOV r2, r0              @r2 = ptrFunc
 MOV r0, r1              @r0 = r1
 BX  r2                  @call ptrFunc

我怀疑你把stack弄乱了。函数int foo(Message* msg)应该保存所有的非易失性寄存器。所以没有必要保存r4-r11,如果我们不使用它们。此外,lr已经设置为返回,因此您可以使用尾部函数优化,直接将jump转换为ptrFunc

还需要注意的是,您可以通过使用函数指针来改进call_from_armC++接口。

 extern int call_from_arm(int (*ptrFunc)(Message* msg), Message* msg);
 /* ... */
 call_from_arm(foo, msg); /* no casting is better! */

正如其他人所说,更多的信息将有助于诊断问题。根据目前的信息,我们只能像我一样猜测。