トップ->アセンブラ 第2章

あなたは

人目のアセンブラの受講生です。

アセンブラ入門内検索

目次

アセンブラ入門

アセンブラ 〜MS-DOSの世界〜 トップ
0. はじめに

1. コマンドラインからの引数
   1. コマンドラインからの引数
   2. 自分の名前は?

2. メモリー管理
   1. 環境変数
   2. 練習問題
   3. メモリーの割り当て
   4. メモリーの解放
   5. UMB
   6. メモリー管理
   7. 常駐プログラム(TSR)

3. 標準入出力
   1. 1文字入力
   2. キーボードバッファー
   3. 1文字出力
   4. 文字列出力
   5. 文字列入力
   6. 練習問題
   7. RS-232C
   8. プリンタ

4. ファイル操作
   1. ファイルオープン
   2. ファイルクローズ
   3. ファイルリード
   4. ファイルライト
   5. 練習問題1
   6. ファイルポインタの移動
   7. 練習問題2
   8. ファイル作成
   9. ファイル属性
   10. ファイル削除
   11. ファイル名変更
   12. ファイル属性の設定・取得
   13. ファイル日時の設定・取得
   14. ファイル検索
   15. 練習問題3
   16. 予約されているファイルハンドル
   17. ファイルハンドルの二重化(リダイレクト)

5. ディレクトリ操作
   1. ディレクトリ操作
   2. カレントディレクトリ変更
   3. カレントディレクトリ取得
   4. ディレクトリ作成
   5. ディレクトリ削除
   6. 練習問題

6. ディスク操作
   1. ディスクのリセット
   2. カレントディスクの取得
   3. カレントディスクの変更
   4. ドライブ情報の取得
   5. 空き容量取得
   6. 練習問題
   7. 交換可能ドライブの検査
   8. リトライ回数の設定
   9. ディスクの直接操作

7. プロセス管理
   1. プログラムの実行
   2. 練習問題
   3. プログラム終了
   4. リターンコード
   5. PSPアドレスの取得・設定
   6. DTAアドレスの取得・設定
   7. プログラムの実行2
   8. 練習問題2

8. その他のシステムコール
   1. 日付の取得・設定
   2. 時間の取得・設定
   3. 割り込みベクタの設定・取得
   4. ベリファイフラグ
   5. MS-DOSのバージョン取得
   6. 国別情報の取得・設定
   7. CTRL + Cの検査
   8. CTRL + Cの処理

9. EMS
   1. EMSとは
   2. EMSを使用するには
   3. EMSが使用可能か?
   4. EMSのバージョン取得
   5. ページフレームのアドレス取得
   6. 未使用ページ数の取得
   7. アロケート、デアロケート
   8. マップ、アンマップ
   9. ページマップのセーブ、リストア
   10. ハンドル数の取得
   11. ハンドルページの取得
   12. 再アロケート
   13. ハンドル名
   14. その他

10. XMS
   1. XMSとは
   2. XMS使用法
   3. XMSバージョンの取得
   4. HMAとは
   5. HMAの割り当て・解放
   6. A20ラインの設定
   7. EMBとは
   8. EMBの空き容量取得
   9. EMBの割り当て・解放
   10. EMBのコピー
   11. EMBのロック・アンロック
   12. EMBハンドル情報取得
   13. EMBの再割り当て
   14. UMBの割り当て・解放

11. エスケープシーケンス
   1. エスケープシーケンスとは
   2. エスケープシーケンス表

12. 終わりに


・ このページの先頭に戻る
・ トップページに戻る



・ このページの先頭に戻る
・ トップページに戻る

トップ-> アセンブラ 第2章-> 第2章.メモリー管理-> 2-7. 常駐プログラム(TSR)

←前ページへ :  トップへ :  次ページへ→



  前のページのプログラムは2つの欠陥があります。1つは前ページも書いたように 解放できないこと。2つめは常駐プログラムに不必要な環境変数領域を開放していないことです。

  1つめの解放方法ですが、フックしている割り込みベクター(今回はINT 21h)の 割り込みベクターを調べ、その領域が自分のプログラムと名前が同じかどうかを調べます。 同じならば、割り込みベクターを戻して、その領域を開放します。

  もし名前が自分と違っていた場合、MCBを追っていけば自分自身を見つけることが できるかもしれませんが、これを解放してしまうと、後から常駐した新しいTSRが 自分を呼びだしているかもしれません。(前のページ部プログラムの「_RETURN」から 4行のように・・・。) しかし呼び出されたときに、呼び出し先が解放されていれば、 暴走してしまいます。このような場合は、解放できません。

  2つめの、環境変数領域の開放ですが、普通のプログラムだと終了と同時にMS-DOSが 解放してくれます。しかし常駐プログラムのような「AH=31h」の システムコールを使用して終了する場合は、自分で解放しなければなりません。 これは以前説明した「AH=49h」のシステムコールを使用して解放できます。

  それではこの2点を改良した、「HOOK21」完成版(?)を示します。

CODE	SEGMENT
	ASSUME	DS:CODE,CS:CODE,ES:CODE,SS:CODE
	ORG	100h

START:
	jmp	short MAIN
TSR:                            	;常駐する部分
	cmp	ah,2ah
	jnz	_RETURN         	;日付取得か?
	mov	cx,1999         	;強制的に1999年
	mov	dx,0101h         	;強制的に1月1日
	mov	al,1            	;強制的に月曜日
	iret                    	;割り込み終了

_RETURN:                        	;正規のINT 21hに飛ぶ
	db	0EAh            	;この4行は決まり文句
_OFF	dw	?               	;実はFAR JUMPしています
_SEG	dw	?
MAIN:
	call	STAY_CHEK
	jnc	REMOVE
STAY:
	mov	ax,[ds:2Ch]
	mov	es,ax
	mov	ah,49h
	int	21h             	;環境変数領域解放

	mov	ax,3521h
	int	21h
	mov	_SEG,es
	mov	_OFF,bx         	;割り込みベクター取得

	mov	dx,offset TSR
	mov	ax,2521h
	int	21h              	;割り込みベクター設定

	mov	ah,9
	mov	dx,offset MSG01
	int	21h             	;メッセージ表示

	mov	dx,offset MAIN
	mov	cl,4
	shr	dx,cl
	inc	dx              	;残る大きさ計算
	mov	ah,31h
	int	21h             	;常駐終了
REMOVE:
	mov	ax,es
	inc	ax
	mov	es,ax

	mov	bx,offset _OFF
	mov	ds,[es:bx+2]
	mov	dx,[es:bx]
	mov	ax,2521h
	int	21h             	;割り込みベクターを戻す

	mov	ah,49h
	int	21h             	;メモリー解放

	push	cs
	pop	ds
	mov	ah,9
	mov	dx,offset MSG02
	int	21h             	;メッセージ表示

	mov	ax,4c00h
	int	21h
;----------------------------------------------
STAY_CHEK:
	mov	ax,3521h
	int	21h             	;割り込みベクター取得

	mov	ax,es           	;解放できるかのチェック
	dec	ax
	mov	es,ax
	mov	di,8
	cld
	mov	si,offset PRCNAME
	mov	cl,7

	repz	cmpsb            	;名前が一緒かのチェック
	or	cx,cx
	jz	_STAY
	stc                     	;解放できない
	ret
_STAY:                           	;解放できる
	clc
	ret
;------------------------------------------
PRCNAME	db	'HOOK21',0
MSG01	db	'常駐しました',0Dh,0Ah,24h
MSG02	db	'解放しました',0Dh,0Ah,24h
	ENDS
	END	START
; 一部のコンパイラでは、
;CODE	ENDS
;	END	START
;と記述しなければいけないようです

C:\>DISPMCB
 MCB  PSP  Name     Size
---- ---- -------- --------
F0F F10 COMMAND  557
113D F10 !・u     89
1197 11AB >ツ8・    18
11AA 11AB COMMAND  361
1314 11AB          89
136E 11AB          7
1376 1519 .        15
1386 1387 DOSKEY   401
1518 1519 COMMAND  361
1682 1519          89
16DC 16EE          16
16ED 16EE DISPMCB  35089

C:\>HOOK21
常駐しました

C:\>DISPMCB
 MCB  PSP  Name     Size
---- ---- -------- --------
F0F F10 COMMAND  557
113D F10 !・u     89
1197 11AB >ツ8・    18
11AA 11AB COMMAND  361
1314 11AB          89
136E 11AB          7
1376 1519 .        15
1386 1387 DOSKEY   401
1518 1519 COMMAND  361
1682 1519          89
16DC 1701          16
16ED 16EE HOOK21   18             ←常駐している
1700 1701 DISPMCB  35070

C:\>HOOK21
解放しました

C:\>DISPMCB
 MCB  PSP  Name     Size
---- ---- -------- --------
F0F F10 COMMAND  557
113D F10 !・u     89
1197 11AB >ツ8・    18
11AA 11AB COMMAND  361
1314 11AB          89
136E 11AB          7
1376 1519 .        15
1386 1387 DOSKEY   401
1518 1519 COMMAND  361
1682 1519          89
16DC 16EE          16             ←解放されている
16ED 16EE DISPMCB  35089

C:\>


←前ページへ :  トップへ :  次ページへ→