ファンクションコール
ついに!文字を表示
今回は、8086CPUではなくMS-DOSについて説明します
MS-DOSは、文字を表示したりキーボードから入力を行う時
プログラムが直接それを行うのではなく、OSが代行します
つまり、プログラムはOSに対してOSが提供しているサービスを要求します
MS-DOSが提供する各種のサービスを要求するには 21 番にシステムコールします
割り込みタイプ21番は特別なシステムコールで、さらに分岐していきます
このシステムコールは AH レジスタの内容によって目的のサブルーチンに分岐するのです
この21番のシステムコールを特別にファンクションコールと呼びます
システムコール 21 -> ファンクションコール AH -> 各種サービス
ファンクション番号はあらかじめ AH レジスタに格納します
この機能を利用すること出始めて、文字の表示や入力が可能になります
さっそくですが、文字を表示してみましょう
スクリーンに文字を表示するには、2番のファンクションをコールします
このファンクションが呼び出されると、DLレジスタの内容を画面に表示します
-A 100
15F2:0100 MOV CX , 1A
15F2:0103 MOV AH , 2
15F2:0105 MOV DL , 41
15F2:0107 INT 21
15F2:0109 INC DL
15F2:010B LOOP 107
15F2:010D
-G =100 10D
ABCDEFGHIJKLMNOPQRSTUVWXYZ
AX=0200 BX=0000 CX=0000 DX=005B SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=010D NV UP EI PL NZ NA PO NC
どうですか、はじめてプログラムの世界に触れたあの日
PRINT命令(または printf() ?) によって、画面に文字列を表示したあの日の感動が甦りませんか?
このプログラムは、DLレジスタに 41 を代入し
表示するたびにインクリメントすることで、A〜Zまでを表示しています
初めて、アセンブリ言語で文字を出力することができましたね
文字列を表示
次は、単一の文字ではなく連続する文字列を表示しましょう
これも、ファンクションコールがサポートしています
文字列の出力は 9 番のファンクションコールが担当しています
このファンクションコールはDXレジスタが指すオフセットアドレスから文字を表示し
終了文字 "$" が見つかった時点で終了します
つまり、DXレジスタのオフセットアドレスを先頭文字として $ まで出力します
-E 200 "Kitty on your lap$"
-A 100
15F2:0100 MOV AH , 9
15F2:0102 MOV DX , 200
15F2:0105 INT 21
15F2:0107
-G =100 107
Kitty on your lap
AX=0900 BX=0000 CX=0000 DX=0200 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=0107 NV UP EI PL NZ NA PO NC
オフセットアドレスの 200 から文字列をあらかじめ代入しておきます
このとき、終了文字となる $ も忘れないで下さい
キーボードから入力
ファンクションコールを用いれば、キーボードから入力を受けることも可能です
文字列の入力には16進数 A のファンクションコールを用います
このファンクションコールは、DXレジスタが指すオフセットアドレスに
1行入力による文字列を格納します。C言語のscanf()関数に似ていますね
ただし、実際にはもう少しややこしい一面があります
まず、入力された文字列を格納するアドレスの先頭1バイト目は
あらかじめ最大入力可能文字数を指定しておかなければなりません
//当然、その分のメモリをあけておく必要がある
入力後、2バイト目は入力された文字数が格納されます
このため、実際に入力された文字列は DX をオフセットアドレスとするメモリの3バイト目からです
-A 100
15F2:0100 MOV AH , A
15F2:0102 MOV DX , 200
15F2:0105 MOV BYTE PTR[200] , 20
15F2:010A INT 21
15F2:010C
-G =100 10C
Kitty on your lap
AX=0A0D BX=0213 CX=0000 DX=0200 SP=FFEE BP=0000 SI=0000 DI=0000
DS=15F2 ES=15F2 SS=15F2 CS=15F2 IP=010C NV UP EI PL NZ NA PO NC
-D 200 212
15F2:0200 20 11 4B 69 74 74 79 20-6F 6E 20 79 6F 75 72 20 .Kitty on your
15F2:0210 6C 61 70 lap
このプログラムを実行すると、入力待ち状態でプログラムが停止し
1行入力し、Enterキーを押すとプログラムが終了します
入力された文字列を格納した位置をダンプすると
たしかに、入力された文字列と文字数が格納されていることを確認できます
プログラムを終了する
前回、システムコールの基本的な動作を学習するために
古い MS-DOS のプログラムの終了システムコールを使いました
しかし、現在ではこれは過去との互換性のために残されているもので
新しい MS-DOS でプログラムを終了するにはファンクションコールを用います
プログラムを終了させるには 4C のファンクションコールを用います
このファンクションコールは AL にリターンコード をあらかじめ格納します
リターンコードとは、C言語で例えると main() 関数の戻り値に相当します
子プロセスから親プロセス、またはOSに対してこのコードを返します
-A 100
15F7:0100 MOV AH , 4C
15F7:0102 MOV AL , 0
15F7:0104 INT 21
15F7:0106
-G =100 106
C:\WINDOWS>
このプログラムを実行すると、debug コマンドを抜け出して
制御が MS-DOS に戻ってしまいます(メモリも解放されるので注意してください)
バッチを当てるなどして、戻り値を調べると良いでしょう
このプログラムは AL レジスタの内容を戻り値として返しています