SEGMENT 文と ENDS 文は、それぞれセグメントの開始と終了を宣言します。/A を指定しない限り、コードやデータを生成する命令は、この 2 つの文の間に記述する必要があります。
構文 name SEGMENT [align] [combine] ['class'] [use-type] name ENDS 例 CSEG SEGMENT BYTE PUBLIC 'CODE' CSEG ENDS SSEG SEGMENT STACK SSEG ENDS SCREEN SEGMENT AT 0A000h SCREEN ENDS
name には、任意のセグメント名を指定します。対になる SEGMENT 文と ENDS 文には、同じ名前を指定する必要があります。同一ソースファイル内に同じ名前を持つ SEGMENT ~ ENDS を複数定義すると、それらは 1 つに結合されます。
align、combine、class、use-type は、セグメント属性と呼ばれます。セグメント属性を省略すると、それぞれのデフォルト値が適用されます。ただし、同一ソースファイルで同じ名前のセグメントがすでに定義されている場合は、そのセグメントの属性が流用されます。
align、combine、class、use-type は、任意の順序で指定できます。
align には、セグメントのアラインメントを指定します。これにより、セグメントの先頭がどれほど「切りのよい」アドレスに配置されるかが決まります。align には、次のいずれかを指定します。
アライン | 境界名 | セグメント先頭アドレスの条件 |
BYTE | バイト境界 | 1 で割り切れるアドレス |
WORD | ワード境界 | 2 で割り切れるアドレス |
DWORD | ダブルワード境界 | 4 で割り切れるアドレス |
PARA | パラグラフ境界 | 16 で割り切れるアドレス |
PAGE | ページ境界 | 256 で割り切れるアドレス |
SEG | セグメント境界 | 10000h で割り切れるアドレス〔Z80/KC160 版のみ〕 |
デフォルトは PARA です。
combine には、同じ名前のセグメントを結合する方法を指定します。「PRIVATE」「PUBLIC」「MEMORY」「STACK」「COMMON」「AT」のいずれかを指定します。デフォルトは PRIVATE です。
PRIVATE
ほかのセグメントと結合しません。
PUBLIC または MEMORY
名前、コンバイン、クラスがすべて同じセグメントと互いに結合します。
STACK
名前、コンバイン、クラスがすべて同じセグメントと互いに結合します。
EXE/COM 形式にするプログラムでは、スタックレジスタの初期値を決定します。MS-DOS/Windows では、プログラムの実行開始時に、SS および SP レジスタがこのセグメントを指すように初期化されます。SS にはこのセグメントの先頭アドレスが設定され、SP にはこのセグメントのサイズが設定されます。つまり、スタック領域をこの属性のセグメントで定義すれば、SS および SP レジスタを初期化する必要がありません。
HEX/BIN 形式にするプログラムでは、PUBLIC と同じです。
COMMON
名前、コンバイン、クラスがすべて同じセグメントを重ね合わせます。各セグメントの先頭アドレスが同じ位置になります。重ねられたセグメントのサイズは、元のセグメントのうち最も大きなセグメントのサイズと等しくなります。
AT paragraph-address
16 ビットセグメントの配置アドレスを絶対的に指定します。paragraph-address は 0 ~ FFFFh の正数で、その 16 倍がセグメントの先頭アドレスになります。
この属性を指定したセグメントにコードやデータを入れたプログラムを LIL で MS-DOS/Windows 用にリンクすると、警告が表示されます。MS-DOS/Windows では、AT 属性のセグメントは、Video RAM などの特定のアドレスにラベルを定義する目的でのみ使用できます。
これに対して、LIL /HEX で HEX コードを作成する場合は、この属性を指定したセグメントにもコードやデータを入れることができます。
PLACE_AT 32bit-address
セグメントを実行時とは異なるアドレスに格納するための属性です。LIL で HEX ファイルを生成する場合に使用します。このコンバイン属性の機能は、リンクオプション /S と同じです。詳細については、「インテル HEX 形式」を参照してください。
class には、セグメントの属するクラスの名前を引用符「'」または「"」で囲んで指定します。同じクラスに属するセグメントは、コンバイン属性にかかわりなく、連続して配置されます。クラス名の大文字と小文字は区別されません。デフォルトのクラス名は、空の文字列(文字が 0 個の文字列)です。空の文字列も 1 つのクラス名と見なされます。
use-type には、「USE16」「USE32」「FLAT」のいずれかを指定します。デフォルトは、.386 以上が指定されていなければ USE16 で、.386 以上が指定されていれば USE32 です。ただし、最初に .MODEL 文がある場合は、.386 以上が指定されていても USE16 がデフォルトになります。
USE16 を指定すると、16 ビットモードで動作している CPU で実行するためのマシンコードが生成されます。USE32 を指定すると、32 ビットモードで動作している CPU で実行するためのマシンコードが生成されます。USE 属性の指定が CPU の実際のモードと矛盾しているとプログラムは正しく動きません。FLAT は USE32 と同じです。
USE16 セグメントには、64KB 以下のコード/データしか配置できません。USE32 セグメントには、4GB までのコード/データを配置できます。
-------------------------------
80286 以下の CPU には 32 ビットモードが存在しないため、.386 以上を指定せずに USE32 または FLAT を指定すると、警告が発生します。
80386 以上の CPU には、16 ビットと 32 ビットの 2 つの動作モードがあります。16 ビットモードで実行するコードは USE16 セグメントに置き、32 ビットモードで実行するコードは USE32 セグメントに置く必要があります。
-------------------------------
MS-DOS では、コンピュータの CPU が 80386 以上であっても、プログラムは常に 16 ビットモードで起動されます。CPU を 32 ビットモードに切り替えるには、そのためのコードを独自に記述する必要があります。モードの切り替えは簡単ではありません。
Windows 95/98/NT では、プログラムは実行ファイルの形式に応じて 16 ビットモードまたは 32 ビットモードで起動されます。現在の LIL は 16 ビット用の実行ファイルしか生成しないため、最初から 32 ビットモードで動作するプログラムを作成するには、他社のリンカを使用する必要があります。
-------------------------------
.USE16 および .USE32 文を使用すると、セグメントの途中でビット属性を変更することができます。
リンク時に先に指定されたオブジェクトファイルのセグメントほど先に(低位アドレスに)配置されます。同じオブジェクトファイルで定義されているセグメントについては、ソースファイル内で先に定義されたセグメントほど先に配置されます。
ただし、同じクラス名を持つセグメントは、連続した位置に配置されます。
さらに、同一クラスのセグメントのうち、PUBLIC (MEMORY)、STACK、COMMON のいずれかのコンバイン属性を持つものは、上の「コンバイン」で説明した規則で互いに結合されます。結合されたセグメントは、連続した位置に配置されるだけでなく、フレームが共有されて完全に 1 つのセグメントになります。たとえば、結合されたセグメント内では相対ジャンプを行うことができます。
なお、グループはフレームを共通化するための疑似セグメントを作成しますが、セグメントの配置には影響しません。
関連付けの種類 | 連続アドレスに配置 | フレームの共有 |
同一クラス | ○ | ラ |
グループ | ラ | ○ |
結合 | ○ | ○ |
リンクマップを作成すると、セグメントの配置を確認できます。