1

これが私のコードです:

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.
4

1 に答える 1

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直接実行することができます。

また、関数ポインタを使用して のC++インターフェイスを改善できることにも注意してください。call_from_arm

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

他の人が述べているように、より多くの情報が問題の診断に役立ちます。現在の情報では、私が行ったように推測することしかできません。

于 2013-04-08T14:23:02.950 に答える