Make your own free website on Tripod.com


アセンブラ(8086系)

その4 基本命令を使った簡単なプログラム1

今回は8086系の基本命令を使って簡単なプログラムを

アセンブラで書いてみます。

どうせならテキストで見かけるようなサンプル的なものではなく

実際に役にたつものを書いてみましょう。


1.機種判定プログラム

よくプログラムを書いているとPC9800系とDOS/V系で処理を分けたい場合があります。

特にハードウェアに密接に関わる部分の場合、PC9800系とDOS/V系では

まったく異なる部分がある為(例えばBIOSコールやI/Oポートの位置など)

現在PC9800系の上で動作しているのか、DOS/V系の上で動作しているのかを

見極める必要があります。(PC9800専用、DOS/V専用といってしまえばそれまでですが)

ここではソフトウェア内で現在動作しているPCの種類を調べるプログラムを書いてみます。


2.プログラムしよう

機種判定には数種類の方法がありますが今回はINT 1Ahを使ったものを書いてみます。


STACK   SEGMENT STACK

        DW    32       DUP(0)

STACK   ENDS

DATA    SEGMENT

MSG1    DB      0Dh,0Ah,'PC9800',0Dh,0Ah,'$'
MSG2    DB      0Dh,0Ah,'DOS/V',0Dh,0Ah,'$'

DATA    ENDS

CODE    SEGMENT
        ASSUME  CS:CODE,DS:DATA,SS:STACK

START:  MOV     AX,DATA
        MOV     DS,AX

        MOV     AH,00h
        MOV     CX,0FFFFh
        INT     1Ah
        CMP     CX,0FFFFh
        JNE     @F

        MOV     DX,OFFSET MSG1
        JMP     DISP_MSG

@@:
        MOV     DX,OFFSET MSG2

DISP_MSG:
        MOV     AH,09h
        INT     21H

        MOV     AX,4C00h
        INT     21h

CODE    ENDS
        END     START


とりあえずこれでPC9800系とDOS/V系の機種判別ができます。

上のプログラムを実行するとPC9800系なら「PC9800」と

DOS/V系なら「DOS/V」と表示されるはずです。



3.解説

上のプログラムの解説をします。

まず1番上の


STACK   SEGMENT STACK

        DW    32       DUP(0)

STACK   ENDS

の部分はスタックの設定です。今回はあまり関係無いので無視しましょう。

ようは32WORD分(WORDは2BYTE)スタックを取っているだけです。(スタックについては後日説明予定)

次の

DATA    SEGMENT

MSG1    DB      0Dh,0Ah,'PC9800',0Dh,0Ah,'$'
MSG2    DB      0Dh,0Ah,'DOS/V',0Dh,0Ah,'$'

DATA    ENDS


はデータセグメントの設定です。

DATAというセグメントのMSG1という場所にあるデータとMSG2という場所にあるデータを

設定しています。ちなみに0Dh,0Ahは改行を表しています。(ASCIIコード参照)

次の


CODE    SEGMENT

から

CODE    ENDS

までが実際に実行されるプログラム(コード)部分です。

        ASSUME  CS:CODE,DS:DATA,SS:STACK

はこのプログラムの各セグメントがどこから始まるか示しています。

CSはCODEからDSはDATAからSSはSTACKから始まるということです。

START:  MOV     AX,DATA
        MOV     DS,AX

ここで何をやっているかというと実はCSとSSはプログラム開始時点で自動的に

CODEとSTACKの値が入るのですが、DSだけは自動的に入らないためセルフサービスで

DSにDATAの値を入れているわけです。それと一度AXに入れてからDSに入れているのは

DSやESなどのセグメントレジスタには直接値を入れられないからです。

        MOV     AH,00h
        MOV     CX,0FFFFh
        INT     1Ah

はINT 1Ahを使う為の準備です。ところでここでINT 1Ahを使用して何をやろうとしているのかというと

DOS/V機でAHに00hをいれてINT 1Ahをコールした場合0時からの経過時間がCX:DXにかえってくるんですね。

PC9800ではこのINT 1Ahというのは普通使用されず何も起こらないわけです。

つまりCXに入れたFFFFhという値がDOS/V機では経過時間に書きかえられ、PC9800では変化しないわけです。

        CMP     CX,0FFFFh
        JNE     @F

        MOV     DX,OFFSET MSG1
        JMP     DISP_MSG

@@:
        MOV     DX,OFFSET MSG2

はINT 1Ahの結果によっての条件分岐を表しています。

JNEは直前の比較が等しくない場合分岐するという意味ですから。

INT 1AhのあとCXがFFFFhから変化した場合すなわちDOS/V機の場合分岐します。

@Fというのは次の@@:と言う意味です。ちなみに前の@@:は@Bです。

分岐しなかった場合DXにはMSG1のOFFSET値(場所)が入り分岐した場合DXにはMSG2のOFFSET(場所)が

入るわけです。

DISP_MSG:
        MOV     AH,09h
        INT     21H

AHに09hを入れてINT 21hを実行するとDS:DXの場所にある文字列を「$」が現れるまで

画面に表示します。DXには先ほどの条件分岐でPC9800の場合はMSG1の場所が

DOS/Vの場合はMSG2の場所が入っているのでそれぞれ機種にあったメッセージが表示されるわけです。

        MOV     AX,4C00h
        INT     21h

AHに4Chを入れてINT 21hを実行するとプログラムの終了処理が行われます。

つまりこれでプログラムは終わりということです。

        END     START

1番最後にあるこの文はここがプログラムの最後でありSTARTという場所からプログラムが

始まるといった意味と思ってください。




PCの機種判別はわかってしまえば簡単ですが見つけるまでが結構面倒なんですね

今回のプログラムでだいたいの機種判別ができますのでいろいろ使い道があると思います。


今回は以上でおしまいです。

次回も引き続きアセンブラの基本について解説する予定です。


そふと工房入口へ戻る