|
アセンブラ関数の作成に関して
インラインの機能や、editer & assembler にて、アセンブラ言語による関数を作成する場合に、知っておくべき事柄について説明します.
(1)関数名
C プログラム内の各関数名は、コンパイルオブジェクト上では、そのままの名前がラベルとして出力されており、関数呼び出しは、単純に当該ラベルを人口とするサブルーチンヘのコールとなっています.このため、アセンブラで作成する関数の人口ラベル名は、C プログラムの中で、呼び出す関数名をそのままつければよいこととなります.
(2)引数の受け渡し
C プログラムの関数呼び出しは、引数を右側から左に向かって評価し、評価結果は、型にかかわらずすべて 2 バイトの大きさで、スタックにプッシュされた後サブルーチンコールされます.
アセンブラ関数に飛び込んできた時のスタックトップには、リターンアドレスが積まれており、さらに、その下には左側の引数が積まれていることとなります。
アセンブラ関数では、リターンアドレスを適当に保存すれば、後は pop 命令により順次、左側からの引数を受け取ることができます.この時、注意しなければいけないのは、アセンブラ関数から戻る時、スタックの深さを変えてはいけないことです.引数のプッシュによるスタックの消費は、呼び出した関数側でもとに戻されるからです.
(3)関数からの戻り値の受け渡し
コンパイラは、関数から戻す値は、すべての場合において hl レジスタにより実現させています.呼び出した関数側においても、hl レジスタに戻り値があるものとして、式のオブジェクト展開がされます.このため、アセンブラ関数から C プログラムに値を渡すためには、hl レジスタに処理結果を格納すればよいこととなります.
(4)レジスタ保護
式の評価の途中でアセンブラ関数が呼ばれるような時でも、呼び出し直前の評価値はスタックに退避されており演算処理にかかわるレジスタ(hl,de,a) の保護は、特に考慮する必要はありません.ただ、bc レジスタは、実行中の関数のスタックフレームのポインタとして使用されていますので、これについては、アセンブラ関数の中で保護しなければなりません.
関数のスタックフレームや、ローカル変数へのアクセス等、コンパイラの出力するオブジェクト展開については、次項に示しておきましたので参考にしてください.
|