2012-09-19 42 views
7

私はARM呼び出し規約に従っているサブルーチンを記述する必要があるARMアセンブリを使用しています(これは別の上位レベルの実装と統合する必要がありますそれ以外の場合はパラメータと戻り値を渡します)。ここでは、アセンブリで作業する際に一般的にわからないことがあります。アセンブリ内のサブルーチンのパラメータと戻り値の受け渡し

したがって、私がよく理解すれば、引数はレジスタr0〜r4から順番に渡され、その後、他の引数のスタックが使用されます。戻り値はr0に渡されます。

ここで私は混乱しています。私がr0のコンテキストを保存してからそれをポップすることになっている場合は、結果を返す方法がありません。最初の引数を破損させることによってしか結果を返せません。どういうわけか回避策はありますか? 先生にありがとう!

答えて

6

r0の戻り値を返すと、の呼び出し元はを呼び出します。呼び出し元は、r0に戻り値がある場所が特にあるため、最初の最初のパラメータと同じ値がr0に含まれているとは考えません。

通常はARM calling convention requires that the subroutine preserves r4 through r11で、r0〜r3ではありません。とにかく矛盾はありません。

+0

関数を呼び出す前に、r0のコンテキストを保存するのは呼び出し元の責任であると思います。 – as3rdaccount

+0

投稿したリンクから:* "r0〜r3:サブルーチンに渡された引数値を保持するために使用され、サブルーチン" *から返された結果も保持されます。 – m0skit0

6

あなた自身で試してみて、コンパイラが何をしているのか見てみませんか?

unsigned int fun (unsigned int a, unsigned int b) 
{ 
    return(a+b); 
} 

arm-none-eabi-gcc -O2 -c fun.c -o fun.o 
arm-none-eabi-objdump -D fun.o 

オブジェクトと分解するコンパイル結果が

00000000 <fun>: 
    0: e0810000 add r0, r1, r0 
    4: e12fff1e bx lr 

である2つの入力A及びBは、R0とR1を使用して渡されます。 r0〜r4は保持する必要はありません。特にr0は戻り値が保持できないためです。したがって、必要とされるCコードが2つのオペランドを一緒に加算され、呼び出し規約に必要な結果がr0に返されます。 r0 = r0 + r1である。

コンパイラは、そうでない場合、コードをコンパイルして特定のコンパイラとターゲットの呼び出し規約についてのかなりの情報を見つけることができるように、生成しないコードを作成する必要があります。

関連する問題