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

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

(1)

識別子について

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

表 9.1

識別子について

C

アセンブリ・プログラム

func1 ( )

_func1

 

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

(2)

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

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

ただし,その際は関数の入口と出口でSPの値が同じになるようにしてください。

また,アセンブラ関数内でレジスタは,自由に使う事ができます(使用前にレジスタの値を退避し,使用後に復帰する必要はありません)。

(3)

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

CC-RLは「関数の戻り先アドレスは“スタック先頭”に格納される」ことを想定したコードを生成します。アセンブラ関数へ分岐するとき,スタック先頭に関数の戻り先アドレスが格納されているので,C言語関数へ戻るときは“ret”を実行してください。

(4)

アセンブラ関数のプロトタイプ宣言

CC-RLではC言語関数から呼び出す関数に対してプロトタイプ宣言が必要です。アセンブラ関数であっても正しいプロトタイプ宣言をしてください。