这是我的代码:
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
问题一直困扰着我好几天。请帮我。感谢
如果我将类消息更改为
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.
答案 0 :(得分:1)
请按以下方式更改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
。
另请注意,您可以使用function pointers改进C++
call_from_arm
界面。
extern int call_from_arm(int (*ptrFunc)(Message* msg), Message* msg);
/* ... */
call_from_arm(foo, msg); /* no casting is better! */
正如其他人所说,更多信息有助于诊断问题。根据目前的信息,我们只能像我一样猜测。