高級言語とのリンク

LASM は MS-DOS 標準形式(Microsoft 形式)のオブジェクトファイルを作成するため、同形式のオブジェクトファイルとならば、それがいかなる高級言語(C,BASIC,FORTRAN,PASCAL など)のコンパイラによるものであっても、リンクすることが可能です。

高級言語とアセンブラをリンクしてプログラムを作成する場合の手順を、次に示します。

(1) 高級言語によるルーチンを作成し、コンパイルする。

(2) アセンブラによるルーチンを作成し、アセンブルする。

(3) 作成されたオブジェクトファイルをリンクする。

メモ この製品に付属のリンカ LIL は、LASM 以外で作成したオブジェクトファイルのリンクには使用できませんので、高級言語とのリンクを行う場合はその高級言語か MS-DOS に付属のリンカを使用してください。

高級言語とリンクするアセンブラルーチンを作成する場合、引数(パラメータ)の渡し方やレジスタの保存など、いくつかの点をその高級言語の規約に合わせなければなりません。しかしこの規約はそれぞれの言語によって異なり、さらには同じ言語でも各コンパイラの間で異なることがあるため、このマニュアルで具体的な説明をすることはできません。高級言語の規約についての詳細は、高級言語コンパイラ側のマニュアルをご覧になってください。

なお、アセンブラコードを出力できる高級言語コンパイラについては、出力させたアセンブラコードを見れば、アセンブラルーチンとのリンク方法を知るうえで大いに役に立つでしょう。

以下では、高級言語ルーチンを呼び出したり、高級言語ルーチンから呼び出されたりするアセンブラルーチンを作成するときの注意事項を述べます。ただしこれらはあくまで一般的な注意事項であり、細かい部分は各コンパイラによって異なることがあります。

NEAR コール/FAR コール

高級言語ルーチンが NEAR コールと FAR コールのどちらのタイプでサブルーチンコールを行うのかを知らなければなりません。アセンブラルーチン中の高級言語ルーチンに対する CALL 文や RET 文のタイプを、それに合わせなければなりません。

セグメント名/グループ名

高級言語ルーチンとの間を NEAR コールによって移行する場合、アセンブラルーチンはその高級言語ルーチンと同じセグメントかグループになければなりません。すなわち、高級言語ルーチンのセグメントと同じ名前で、かつ PUBLIC コンバイン属性を持つセグメントか、高級言語ルーチンのセグメントと同じグループに所属するセグメントを定義しなければなりません。要点は高級言語ルーチンと同じフレームからアセンブラルーチンが参照できるということです。同様のことは、NEAR 属性のグローバルデータを共有する場合についても当てはまります。

MS-C や TURBO C とのリンクに関しては、簡略化セグメントディレクティブによるセグメント定義がそのまま使用できます。

識別子名

高級言語におけるサブルーチン、関数、変数などの名前(識別子)をどのような綴りでアセンブラから参照すればよいのか注意してください。高級言語の識別子は基本的にはそのままの綴りでオブジェクトファイルに書き込まれますが、C 言語のように前にア

ンダーライン「_」を付けるものもあります。

引数(パラメータ)の受け渡し方法

多くの場合、高級言語ルーチンには引数がありますが、この引数の受け渡し方法を知らなければになりません。次の点に注意してください。

・受け渡しの場所

スタック上、レジスタ上などがあります。ほとんどの場合はスタック上です。

・受け渡しの順番

スタックによる受け渡しの場合、引数の順番も重要です。2 つ以上の引数が存在する場合、一般に C 言語では後ろの引数から順にスタックにプッシュしますが、BASIC、FORTRAN、PASCAL では前の引数から順にプッシュします。

・引数の取り除き

スタックによる受け渡しの場合、引数のために使用されたスタックの復元を、呼び出し側と呼び出され側のどちらのルーチンが行うのかに注意してください。一般に C 言語では呼び出し側が、FORTRAN や PASCAL では呼び出され側がこの処理を行います。

・変数の内部形式とサイズ

高級言語の変数はそのタイプ(型)によって内部形式が決まっています。整数では 2 バイト、4 バイト型、実数では 4 バイト IEEE 形式、8 バイト IEEE 形式などが代表的ですが、文字列の内部形式は言語によって違います。

・値渡しとポインタ渡し

同じ内部形式の変数でも、その値そのものをを渡す場合(値渡し)と、その変数のアドレスを渡す場合(ポインタ渡し)とがあります。たとえば C 言語では値渡しが基本であり、FORTRAN ではポインタ渡しが普通です。

返り値の受け渡し方法

関数ルーチンには返り値がありますが、この受け渡し方法を知らなければなりません。AX、DX レジスタや数値演算コプロセッサの ST レジスタ(実数の場合)などが使用されることがあります。

レジスタの保存

高級言語ルーチンでは、それぞれのルーチンで内容を保存しなければならないレジスタが決まっています。高級言語ルーチンから呼び出されるアセンブラルーチンでこれらのレジスタを使用するときは、前もってそのレジスタの値をスタックなどに記憶しておき、レジスタの使用後に復元するようにしなければなりません。

スタートアップルーチン

通常、高級言語にはプログラムの最初に実行しておかなければならないコード(スタートアップルーチン)が存在します。プログラムをアセンブラルーチンから始めるとこのスタートアップルーチンが実行されず、高級言語ルーチンが正しく作動しないことも考えられるため、プログラムの開始部分は高級言語ルーチンにする方がよいでしょう。

[目次]