ASSUME 文は、セグメントレジスタの値をアセンブラに通知します。ASSUME 文では、各セグメントレジスタにフレームを関連付けます。言い換えると、各セグメントレジスタの値をどのように仮定してコードを生成すべきかをアセンブラに通知します。
構文 ASSUME seg-register:frame [, ...] ASSUME NOTHING 例 ASSUME CS:CSEG, DS:DSEG, ES:NOTHING, SS:SSEG ASSUME NOTHING
seg-register には、「CS」「DS」「ES」「SS」のいずれかを指定します。.386 以上を指定した場合は、「FS」「GS」も指定できます。
frame には、セグメント名、グループ名、演算子 SEG による式、またはキーワード「NOTHING」を指定します。
「ASSUME NOTHING」と指定すると、すべてのセグメントレジスタに対して「NOTHING」が指定されます。「NOTHING」と指定されたセグメントレジスタは、ラベルの参照に暗黙に使用されることはありません。
-------------------------------
ASSUME 文はアセンブラに対する宣言を行うだけで、セグメントレジスタの値を設定するコードを生成するわけではありません。セグメントレジスタの実際の値は、OS によって初期化されている場合もありますが、初期化命令を独自に記述しなければならない場合もあります。
ASSUME 文を省略すると、参照するラベルの属するセグメントの先頭に必要なセグメントレジスタが設定されているという仮定のもとでコードが生成されます。
グループを使用する場合は、セグメントレジスタがセグメントとグループのどちらに位置付けられているかを明示する必要があるため、ASSUME 文による宣言が重要になります。ASSUME による宣言と現実のセグメントレジスタの値が矛盾すると、正しいコードが生成されません。
例1:データの参照
次のコード例で説明します。
DGRP GROUP DSEG1, DSEG2 DSEG1 SEGMENT WORD D1 DW ? DSEG1 ENDS DSEG2 SEGMENT WORD D2 DW ? DSEG2 ENDS ASSUME XXX CSEG SEGMENT MOV AX, [D1] MOV AX, [D2] CSEG ENDS
「ASSUME XXX」の指定により、2 つの MOV 命令から生成されるコードが変わります。
「ASSUME DS:DSEG1, ES:DSEG2」とすると、次のコードが生成されます。
MOV AX, DS:[D1] ' オフセットは DSEG1:D1 = 0 MOV AX, ES:[D2] ' オフセットは DSEG2:D2 = 0
「ASSUME DS:DGRP」とすると、次のコードが生成されます。
MOV AX, DS:[D1] ' オフセットは DGRP:D1 = 0 MOV AX, DS:[D2] ' オフセットは DGRP:D2 = 2
この例では、2 番目の MOV 命令から生成されるマシンコードが異なっています。したがって、これらの MOV 命令が実行されるときの実際のセグメントレジスタの値を正しく ASSUME で宣言しておかないと、生成されたコードは正常に実行されません。
使用できるセグメントレジスタが複数存在する場合もありますが、このときは最も効率のよいコードを生成するレジスタが使用されます。たとえば、上の例で「ASSUME DS:DSEG1, ES:DGRP」と指定すると、次のコードが生成されます。
MOV AX, DS:[D1] ' オフセットは DSEG1:D1 = 0 MOV AX, ES:[D2] ' オフセットは DGRP:D2 = 2
D1 は DS と ES のどちらを使用しても参照できるため、効率のよい DS が使用されます。D2 は ES でしか参照できないため、ES が使用されます。
例2:ジャンプ
もう 1 つ例を示します。
ASSUME CS:CSEG1 CSEG1 SEGMENT JMP FAR PTR L1 CSEG1 ENDS ASSUME CS:CSEG2 CSEG2 SEGMENT L1: CSEG2 ENDS
この場合は、ラベル L1 にジャンプしたときに CS レジスタの値が CSEG2 の先頭を指すようなコードが生成されます。ジャンプ命令の場合は、JMP 命令のある場所での ASSUME 指定ではなく、飛び先のラベルのある場所での ASSUME 指定が意味を持つことに注意してください。
これに対して、ASSUME 文を変更した次のコードでは、異なるコードが生成されます。
ASSUME CS:CGRP CGRP GROUP CSEG1, CSEG2 CSEG1 SEGMENT JMP FAR PTR L1 CSEG1 ENDS CSEG2 SEGMENT L1: CSEG2 ENDS
この場合は、ラベル L1 にジャンプしても CS レジスタの値が CGRP のままで変化しないようなコードが生成されます。このコードでは CS が変化しないため、FAR ジャンプは NEAR ジャンプに変更できます。これに対して、最初のコードで FAR ジャンプを NEAR ジャンプに変更すると、共通のフレームから参照できないラベルに対して自己相対ジャンプが行われたことを示す警告が発生します。