Everything
9.2 C言語からアセンブリ言語ルーチンの呼び出し

C言語関数からアセンブラ関数を呼び出すときの注意点について説明します。

(1)

識別子について

CC-RHではCソース内で外部名,たとえば,関数や外部変数が記述された場合,それらの名前をアセンブラへ出力すると,先頭に“_(アンダースコア)”を付けた名前になります。

表 9.1

識別子について

C

アセンブラ

func1 ( )

_func1

アセンブラ命令で関数や外部変数を定義するときは,識別子の先頭に“_”をつけ,C言語関数から参照するときは“_”を取った形で行ってください。

(2)

スタック・フレームに関して

CC-RHは「スタック・ポインタ(SP)が,常にスタック・フレームの最下位アドレスを指している」ことを想定したコードを出力します。そのため,Cソースからアセンブラ関数へ分岐後は,アセンブラ関数内では,SPの指すアドレスよりも下位のアドレス領域は自由に使用することができます。逆に上位のアドレス領域の内容を変更した場合,C言語関数で使用していた領域を破壊することにつながり,以降の動作を保証できませんので注意が必要です。上記を回避するためには,アセンブラ関数の先頭でSPを変更してからスタックを使用してください。

ただし,その際は呼び出しの前後でSPの値が保持されるようにしてください。

また,アセンブラ関数内でレジスタ変数用レジスタを使用する場合は,アセンブラ関数の呼び出し前後でレジスタ値が保持されるようにしてください(使用前にレジスタ変数用レジスタの値を退避し,使用後は復帰してください)。

レジスタ変数用レジスタは,レジスタ・モードにより異なります。

表 9.2

レジスタ変数用レジスタ

レジスタ・モード

レジスタ変数用レジスタ

22レジスタ・モード

r25,r26,r27,r28,r29

32レジスタ・モード

r20,r21,r22,r23,r24,r25,r26,r27,r28,r29

(3)

C言語関数への戻り先アドレス

CC-RHは「関数の戻り先アドレスは“リンク・ポインタlp(r31)”に格納される」ことを想定したコードを生成します。アセンブラ関数へ分岐するとき,lpに関数の戻り先アドレスが格納されているので,C言語関数へ戻るときは“jmp [lp]”を実行してください。