-

Linker Reference Manual

提供: HI-TECH C for CP/M Fan WIKI(JP)
移動先: 案内検索

リンカ

HI-TECH Cはリロケータブルアセンブラとリンカを連携させておらず?Cのソースファイルを別々にコンパイルすることを許可しています。これは、プログラムをいくつかのソースファイルに分割してよい、ということを意味します。そして、それらは編集やコンパイルが簡単なファイルサイズに留めておくことができ、それぞれのオブジェクトファイルをリンクして、一つの実行ファイルにします。アセンブラは機種依存のマニュアルで記述されます。この付録では背後にある理論と。リンクの使用方法を記述します。

リロケーションとPSECTS

リンカの基本的な役割はいくつかのリロケータブルオブジェクトを一つに連結することです。このオブジェクトファイルがリロケータブルと呼ばれるのはファイルがその中に十分な情報を持っているおり、ファイル内のプログラムやデータアドレス(関数へのアドレスなど)への参照が、リンク処理後、最終的にファイルがメモリ内で配置される位置に応じて調整されるためです。

そのため、ファイルがリロケータブルと呼ばれるのです。 再配置は二つの基本的な形態を取ります。名前によるリロケーション、つまりグローバルシンボルの最終的な値と、PSECTによるリロケーション、つまりコードのある部分のベースアドレスによるリロケーションです。

プログラムのセクション?

どのオブジェクトファイルも一つやそれ以上、PSECTとして参照されるプログラムセクションとしてメモリに格納されるデータバイトを含んでいます。このPSECTがプログラム内のコードバイトのある種の論理的グループを表します。実行可能な命令を含むプログラムのセクションは普通、テキストPSECTとして参照されます。他のセクションは初期化されたデータPSECTで、BSS PSECTと呼ばれます。

実際のところ、リンカはいくつでもPSECTを扱え、実際に特別なアプリケーションでは多くが使われます。しかし、Cコンパイラは上述の3つのみを使い、text, data, bssという名前で単純に区別します。リンカはPSECTの名前に対して、特別に区別して割り当てたりはしません。

DATAとBSSのPSECTの違いは2つの外部変数で例示できます。1つ目は数値の1から始まるもの、もう1つは1から始まらないものです??最初のものはDATA PSECTに配置され、2つ目のはBSS PSECTに配置されます。BSS PSECTはプログラムの開始時に常にゼロでクリアされ、2つ目の変数は実行時にゼロで初期化されます。しかしながら最初のものはプログラムファイルの中でスペースを取り、スタートアップ時に初期化の数値1が使われます。これは実行時にDATA PSECT変数内の数値を変更することは可能ですが、ベタープラクティスとしてはそうしません。なぜならこれは多くの変数を常に使うことになり、再起動可能でROM化可能なプログラムを許可します??

TEXT PSECTは全ての実行可能な命令が置かれるセクションに対するものです。CP/M80では普通、TEXT PSECTは実行開始されるTPAのベースから始まります。DATA PSECTは普通、TEXT PSECTに続き、BSSが最後になります。BSSはプログラム(.COM)ファイル内でスペースをとりません。このPSECTの順序づけはリンクのオプションでオーバーライドされるかもしれません。これは特殊なハードウェア用のコードには特に便利です。

MS-DOSやCP/M-86でも同じ順になりますが、8086プロセッサがリロケーションを提供するセグメントレジスタを持つため、TEXT,DATA PSECTのどちらも0から始まります。次々とメモリにロードされていきますが。

これは64kコードや64kデータ、スタックを許容します。オペレーティングシステムがメモリにプログラムをロードするのに十分な情報が、実行ファイル(.EXEや.CMD)内に置かれます。

ローカルPSECTとLargeモデル

8086の実際的な目的では、PSECTが64kに制限されます。64k以上を許可するには、コンパイラがローカルPSECTを作成します。.psectディレクティブPがLOCALフラグを持つと、PSECTがローカルであるとみなされます。ローカルPSECTが何個でも、また同じ名前であっても他のモジュールから、連結することなくリンクできます。

同じモジュール内の(もしくは同じライブラリ内の)ローカルPSECTへの全ての参照は同じPSECTへの参照として扱われます。しかしながらモジュール間においては、同じ名前の2つのPSECTが区別されます。

-Pオプション(後述)を介して、ローカルPSECTの参照を許可するために、ローカルPSECTが、それに関連づけられたクラス名を持ちます。

これは.psectディレクティブにCLASSフラグを持つことで実現されます。

グローバルシンボル

リンカは、アセンブラに対してグローバルに宣言されたシンボルだけを扱います。Cソースレベルから、これはストレージクラス名とスタティックとして定義されている全ての名前を意味します??これらのシンボルは、それが定義されているモジュール以外から参照されます。グローバルシンボルの定義を参照と比べるのはリンカの仕事です。

オペレーション

リンカへのコマンドは次の形態を取ります。

LINK options files ...

Optionsはゼロかそれ以上のリンカオプションで、どれもがリンカの振る舞いを何らかの形で変更します。Filesは1つかそれ以上のオブジェクトファイル、そしてゼロかそれ以上のライブラリ名です。optionsはリンカによって、次のように認識されます。これらは大文字もしくは小文字で認識されます。

-R
アウトプットをリロケータブルのままにします。
-L
絶対的なリロケーション情報を維持します。-LMはセグメントリロケーション情報のみを維持します。
-I
未定義シンボルを無視します。
-N
アドレスでシンボルをソートします。
-Caddr
addrによりバイナリ出力ファイルオフセットを生成します。
-S
出力ファイルからシンボル情報を抜き出します。
-X
出力ファイル内のローカルシンボルを抑制します。
-Z
出力ファイル内の(コンパイラが生成した)些細なシンボルを抑制します。
-Oname
出力ファイルnameを呼び出します。
-Pspec
specはPSECTの位置定義です。
-Mname
ファイルnameにリンクマップを書き出します。
-Usymbol
symbolを初期未設定にします。
-Dfile
シンボルfileを書き出します??
-Wwidth
マップの幅を設定します。

これらを順に取り上げます。

-Rオプションはリンカに対して出力ファイル(-Oオプションでつけた名前かデフォルトのl.obj)をリロケータブルのままにするよう命令します。これは、たいていの場合リンクされるファイルがとても多く??、リンクの出力が続くリンクの入力として使われるからです??。 このオプションが、なければ、リンカは出力ファイルを絶対的なものとして、全てのリロケータブルアドレスを絶対的な参照とします。このオプションは-Lや-Cオプションと一緒には使えません。

-Lオプションはリンカに対して、ファイルが絶対的であってもヌルリロケータブル情報を出力させます。この情報はセルフリロケータブルなプログラムに対して実行時にアドレスをリロケートさせなければいけないと教えます??このオプションは-Cオプションと一緒には使えません。実行ファイル(つまり.COMファイル)を生成するためにobjtohexを使う必要があります。

-LMオプションが使われた場合、セグメントリロケーション情報のみが保たれます。これはlargeメモリモデルとの結合に使われます。objtohexはセグメントリロケーションアドレスを実行ファイルに挿入する際にリロケーション情報を(-Lをつけて起動することで)使います。

-I オプションは、どのモジュール内でも定義されていないシンボルを含むコードをリンクしたい時に使われます。これはトップダウン型の開発時に、ルーチン自体がコーディングされる前に参照するルーチンが書かれる時に、普通使われます。

リンクマップを-Mオプションを介して取得する時に、シンボルテーブルがデフォルトでシンボルネームがソートされます。アドレス順にソートする場合は-Nオプションが使えます。

リンカの出力はデフォルトでオブジェクトファイルです。実行可能なプログラムを作るには、これを実行可能なイメージに変換する必要があります。CP/Mでは.COMファイルで、これは100Hの位置から始まり、メモリ上に見えているシンプルな実行プログラムイメージです。

リンカは-C100Hオプションで、このようなファイルを生成します。他のアプリケーションが要求するイメージバイナリファイルフォーマットも-Cオプションで生成されます。-Cに続くアドレスは10進数(デフォルト)8進数(oかOのサフィックス)、16進数(hかHのサフィックス)で与えられます。

MS-DOSやCP/M-86のファイルフォーマットの複雑さにより、LINKはこれら(.EXEや.CMDなど) のフォーマットを直接生成しません。コンパイラが自動的にOBJTOHEXを適切なオプションで実行し、正しいファイルフォーマットを生成します。

-S, -X, -Zは-Cオプションが指定されているときは意味がなく、全てのシンボル、もしくはささいなローカルシンボルを出力ファイルから。それぞれ取り除きます??ささいなシンボルはコンパイラによって生成され、数字の文字列に続くアルファベットの複数文字を持ちます。

-Cオプションが使われた時のデフォルトの出力ファイルの名前はl.objもしくはl.binです。これは-Onameオプションでオーバーライドされます。

このインスタンスでは出力ファイルはnameで呼ばれます。この名前には拡張子がつかないことに気をつけてください。ファイルはオプションの引数通りに呼び出されます。

ある種の特別なアプリケーション、たとえば組み込みマイクロプロセッサ用のものなどでは、いろいろなPSECTが配置されるべきアドレスをリンカに指定する必要があります。これは-Pオプションで行えます。これはそれぞれがオプションの指定アドレスを持つ、コンマ区切りのPSECT名のリストで構成された、指定を伴います。

リストにあるPSECTアドレス指定がない場合、その前のPSECTと連結されます。以下はその例です。

-Ptext=0c000h,data,bss=8000h

これは0C000Hに配置されるTEXT PSECT、TEXT PSECTの終わりから始まるDATA PSECT、8000Hから始まるBSS PSECTです。これは0C000HからのROM、8000HからのRAMを持つプロセッサ用でしょう。

実行時にコードのアドレスが決まり、出力ファイル内でのアドレスオフセットであるロードアドレスが異なる(例えば8086)リンクアドレスでは、ロードアドレスをリンクアドレスとは別個に指定できます。以下はその例です。

-Ptext=100h/0,data=0C000h/

実行用のリンクは100hですが、出力ファイルは0にロードされます。他方で データセグメントは0C000hにリンクされますが、ファイル内ではTEXT PSECTに近接しています。 スラッシュ(`/') が省略された場合、ロードアドレスはリンクアドレスと同じになります。スラッシュが与えられてもその後にアドレスが続かない場合、PSECTはその前のPSECTの後にロードされます。

ローカルアドレスのリンクアドレスとローカルPSECTのロードアドレスを指定するためには、PSECTが属するグループの名前をグローバルPSECTの代わりに使います。 ローカルPSECTは-Pオプションで指定されたアドレスにリンクされ、指定されたロードアドレスから1つずつ増えながらロードされます。

-Mnameオプションはリクエストマップを要求します。 これはシンボルテーブルと、ファイルnameに書き出すモジュールロードアドレス情報を含みます。nameが省略された場合、マップは標準出力に書き出されます。-Wはマップを好きな幅に指定するために使われます。

-Uオプションはリンカに対して、シンボルテーブルに未定義として最初に入力されるシンボルを指定します。これはライブラリから全体を読み込む時に便利です。1つ以上の-Uフラグが使用できます。

リンクされたプログラムに対して、デバッガを使いたい場合、シンボルファイルを生成するのが便利です。-Dfileオプションでは、file名のファイルに対して、fileに何も与えられなかった時はl.symに対してシンボルファイルが書き出します。

シンボルファイルは一行ごとにアドレスリストとシンボルで構成されます。

ここではいくつかのリンカの使い方の例を挙げます。しかし、普通の場合は明確にリンカを呼び出す必要はありません。というのはそれは自動的にCコマンドから呼び出されるからです。

LINK -MMAP -C100H START.OBJ MAIN.OBJ A:LIBC.LIB

このコマンドはファイルstart.objとmain.objをライブラリa:libc.libとリンクします。ライブラリから要求されるこれらのモジュールのみが実際にリンクされます。出力はデフォルトファイルl.binの中に.COMフォーマットで格納されます。ファイル名mapの中にマップも書き出されます。ファイルstart.objはスタートアップコードを含んでいなければならず、また実際、このファイルの最低アドレスのコードは、100Hにあるためプログラム開始時に実行されます。

LINK -X -R -OX.OBJ FILE1.OBJ FILE2.OBJ A:LIBC.LIB

ファイルfile1.objとfile2.objはa:libc.libからの必要なルーチンとリンクされ、x.objを残します。このファイルはリロケータブルのままです。未定義シンボルはエラーを引き起こしません。ファイルx.objはきっと後ほど他からリンクで呼び出されることでしょう。全てのローカルシンボルはアウトプットファイルから抜き出せますので、スペースを省略できます。

リンカの呼び出し

リンカにはLINKと呼ばれ、CP/M以下のA:ドライブにあるか、もしくはMS-DOSの:\HITECH\にあります。標準入力からの直接入力をプロンプトでする場合、引数無しでも呼び出せます。標準入力がファイルの場合、プロンプトは表示されません。CP/Mはデフォルトで大文字に全てのコマンドラインを変換してしまいますが、このやり方だと、入力は小文字が入っていてもかまいません。これは-Uや-Pオプションで便利です。この呼び出し方はLINKに渡す引数がの数が多い時に便利です。ファイルのリストが行に対して長すぎる場合でもバックスラッシュ('\') を先行する行の最後に置くことで、行を続けることができます。この方法ではLINKはほぼ制限のない長さのコマンドを発行できます。