以下では、付属のサンプル プログラム HELLO.ASM について解説します。
1 ;------------------------------------ 2 ; サンプルプログラム HELLO.ASM 3 ; 「Hello !」と表示します 4 ;------------------------------------ 5 ASSUME CS:CSEG, DS:DSEG, SS:SSEG 6 CSEG SEGMENT WORD 7 START: MOV AX, DSEG 8 MOV DS, AX 9 MOV DX, OFFSET MSG ; DS:DX で MSG を指す 10 MOV AH, 9h 11 INT 21h ; 文字列 MSG を表示 12 MOV AX, 4C00h 13 INT 21h ; プログラムを終了 14 CSEG ENDS 15 16 DSEG SEGMENT WORD 17 MSG DB 'Hello !', 0Dh, 0Ah, '$' 18 DSEG ENDS 19 20 SSEG SEGMENT STACK 21 DB 100h DUP(?) 22 SSEG ENDS 23 24 END START ; 実行開始アドレスは START
このプログラムは基本的な EXE 形式用プログラムであり、このマニュアルでも随所で引用しています。
5 行目の ASSUME 文では関係するセグメントレジスタの値を LASM に教えます。実際には DS レジスタは 8 行目でセットされるのですが、それまでの間に ASSUME 文の宣言を使用するような文はないので、このずれはかまいません。
6 行目から 14 行目はコード用のセグメント CSEG です。
8 行目と 9 行めで、DS:DX がセグメント DSEG にあるメッセージ MSG を指すようにセットします。
10 行目と 11 行目で文字列表示の MS-DOS ファンクションリクエストを実行します(このファンクションリクエストは先にセットした DS:DX の値を参照します)。これで表示が終りました。
12 行目と 13 行目ではプログラム終了の MS-DOS ファンクションリクエストを実行します。これによりプログラムは終了し、MS-DOS に戻ります。
17 行目は表示させるメッセージ用のデータです。「Hello !」に続く「0Dh」は復行を、「0Ah」は改行を指示します。「$」は表示データの終わりを宣言しています。
16 行目から 18 行目はデータ用にセグメント DSEG を定義していますが、このプログラムの場合はメッセージデータもコードと同じセグメントに置くこともできます。
20 行目から 22 行目はスタックセグメントです。コンバインタイプ「STACK」で定義しているので、SS、SP 両レジスタはこのセグメントに合わせて自動的に初期化されます。
21 行目はスタックセグメントの大きさを決めています。100h バイトというのは、これくらいあれば十分(十分すぎるくらい)だろうということです。
24 行目の END 文は、すべてのソースファイルに必ず必要です。「START」では実行を開始する位置をラベル START に指定しています。
以下では、付属のサンプル プログラム HELLOC.ASM について解説します。
1 ;------------------------------------ 2 ; サンプルプログラム HELLOC.ASM 3 ; 「Hello !」と表示します . 4 ; COM 形式版 5 ;------------------------------------ 6 ASSUME CS:CSEG, DS:CSEG 7 CSEG SEGMENT 8 ORG 100h 9 MOV DX, OFFSET MSG ; ここがプログラムの開始点 10 MOV AH, 9h 11 INT 21h 12 MOV AX, 4C00h 13 INT 21h 14 MSG DB Hello !', 0Dh, 0Ah, '$' 15 CSEG ENDS 16 END
このプログラムは前述の HELLO.ASM を COM 形式用に変更したものです。HELLO.ASM から変更した点を説明します。
8 行目では最初の 100h バイト(256 バイト)を飛ばしています。この 100h バイトに PSP という MS-DOS のデータが自動的に挿入されるためです。
9 行目からプロセッサ命令が始まりますが、前述の HELLO.ASM と違って DS レジスタのセットをしていません。COM 形式ではセグメントレジスタはプログラムの先頭に自動的にセットされているからです。
14 行目はメッセージ用のデータですが、コードと同じセグメントにあります。セグメントレジスタを動かせないため、通常 COM 形式プログラムではセグメントを 1 つしか定義しません。データは、命令コードとして実行されないような位置に置かなければなりません(このプログラムでは命令コードの実行は 13 行目で終ります)。
16 行目の END 文ではプログラムの実行開始地点を指定していません。COM 形式プログラムは、常にプログラムの先頭から 100h バイト目を実行開始地点とするからです。