2016-10-24 20 views
0

obj-cに構造体があります。この構造体へのポインタを、私が書いたアームアセンブリ関数に渡します。コードにステップインすると、ポインタが正常に渡され、私のasmコード内から構造要素の値にアクセスして変更できることがわかります。人生は良いです - 私がasm関数から戻るまで。呼び出し元のobj-cコードに戻った後、構造体の値はすべてホースされます。なぜ私は理解できません。以下は私のコードの関連する部分です。ここでobj-c構造体へのポインタ構造体を渡す関数 - 破損

struct myValues{ // define my structure 
int ptr2A; // pointer to first float 
float A;   
float B;   
float C; 
float D; 
float E; 
float F; 
}myValues; 

struct myValues my_asm(int ptr2a, float A, float B, float C, float D, float E, float F); // Prototype for the ASM function 

…code here to set values of A-F... 

float* ptr2A = &myValues.A; //get the memory address where A is stored 
myValues.ptr2A = ptr2A;   //put that address into myValues.ptr2A and pass to the ASM function 


// now call the ASM code 
myValues = my_asm(myValues.ptr2A, myValues.A, myValues.B, myValues.C, myValues.D, myValues.E, myValues.F); 

は私のasmコードの関連する部分である:

mov r5, r1  // r1 has pointer to the first float A 
vdiv.f32 s3, s0, s0 //this line puts 1.0 in s3 for ease in debugging 
vstr s3, [r5] // poke the 1.0 into the mem location of A 
bx lr 

私はコードをステップ実行するとすべてが期待どおりに動作し、私は一度、Aのメモリ位置に1.0で終わるしかし、私はreturn(bx lr)を実行し、呼び出し元のobj-cコードに戻り、私の構造体内の値がガベージになる。私はABIとAACPSを掘り下げましたが(おそらく初心者のように成功するかもしれませんが)、これを理解することはできません。 "bx lr"の後に何が起こって構造を乱したのですか?

以下は、私のasmコードの "Rev 1"です。私はこれらの行を除くすべてを削除しました:

_my_asm: 
vdiv.f32 s3, s0, s0 // s3 = 1.0 
vstr s3, [r1] 
bx lr 

これは私にとっては解決策でした。以下は、私のobj-cコードの関連部分の "Rev 2"です。私は構造体のコピーを渡すことでポインタを渡していました - 完全にホース。このコードは、私の構造体の最初のfloatへのポインタを渡すだけです...私のasmコードは汎用レジスタr0からピックアップします。男、私は頑張ります。 ;-)

void my_asm2(int myptr); // this is my prototype. 

私は私のOBJ-CコードからASM2コードを呼び出す場所です:

my_asm2(&myValues.A); 

マイASM2コードは次のようになります。要約すると、そう

_my_asm2:     ; @simple_asm_function 
// r0 has pointer to the first float of my myValues structure 
// Add prolog code here to play nice 
vdiv.f32 s3, s0, s0 //result S3 = 1.0 
vstr s3, [r0]   // poking a 1.0 back into the myValues.A value 
// Add Epilog code here to play nice 
bx lr 

私は今、私の構造体myValuesへのポインタをASMコードに渡すことができ、ASMコードの中で、それらのメモリ位置に新しい値をポックすることができます。私が呼び出したobj-cコードに戻ると、すべてが期待どおりです。この趣味と共に私を助けてくれる人に感謝します。 :-)

+0

戻る前に何かを復元できないように思えます:*サブルーチンはr4からr11の内容とスタックポインタ*を保持しなければなりません。ルーチンの残りの部分を見ずにもっと言うことは難しいです。 –

+0

あなたの記事を読んだ後、私はasm関数を3行に減らしました(上記の "Rev 1"を参照)。私は一般的なレジスタやspに触れません。まだ同じ結果が得られています。私はコードをステップ実行し、予想通りにメモリ位置に1.0を取得します。次に "bx lr"を横切ってステップし、呼び出すobj-cコードに戻ったら構造体の値はゴミです。 – relayman357

+0

私はARMアセンブラに慣れていませんが、関数に引数を渡すので、戻る前または後にスタックを復元する必要はありませんか? –

答えて

0

ここでの解決策は、構造体の最初のfloat変数のメモリ位置を指すポインタをアセンブリ関数に渡すことです。アセンブリ関数がこれらのメモリ位置に行った変更は、呼び出し元関数に戻ってもそのまま残ります。これは、アセンブリコードを呼び出して、そのコードを既存のデータ構造(この場合はmyValues)で操作する場合に適用されます。

関連する問題