ASSUME

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 ジャンプに変更すると、共通のフレームから参照できないラベルに対して自己相対ジャンプが行われたことを示す警告が発生します。

参照 SEGMENTGROUP

[目次]