从arm程序集调用c函数时,堆地址发生了移位
Address of heap shifted while calling c function from arm assembly?
下面是我的代码:
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_arm
的C++
接口。
extern int call_from_arm(int (*ptrFunc)(Message* msg), Message* msg);
/* ... */
call_from_arm(foo, msg); /* no casting is better! */
正如其他人所说,更多的信息将有助于诊断问题。根据目前的信息,我们只能像我一样猜测。
相关文章:
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 这C++代码中发生了什么C++(指数函数)
- 哪种方式更快?究竟发生了什么,我们没有看到什么?
- 我正在将一个 std::string 传递给一个 boost 函数,该函数对该类型进行常量引用,但该值发生了变化
- c++问题:给一个变量赋值后,另一个变量发生了变化
- 从"LLONG_MAX 秒"构造 std::chrono::毫秒变量时发生了什么?
- 这个片段中关于 n 在 pc[i] 中的表示发生了什么
- istringstream,num1 和 num2 在这里发生了什么?
- 究竟发生了什么,我们需要在 c++ 中双重调度/访客
- libstdc++的make_shared布局在gcc 4.x和gcc 6.x之间是否发生了变化?
- 我是否能够确定在部署一个程序后发生了什么,我在数组末尾写入?
- 为什么我的 int 在 C++ 程序中间发生了变化?
- 这个阶乘程序内部发生了什么?
- C++ - *(int**) 地址?这里发生了什么?
- C++用用户输入在循环中填充 char 数组:输入整个字符串时到底发生了什么?
- 在使用VS2010构建ACE和TAO(CORBA)时发生了许多错误
- 为什么在波纹管程序中发生了从字符串常量到'char*'的警告已弃用的转换
- 让对象知道它创建的 show 函数中发生了什么
- 从arm程序集调用c函数时,堆地址发生了移位
- 当调用new函数时,返回地址值发生了什么?