←練習問題へ :  INDEX :  次の章へ→


4-9.練習問題

問題
文字列を入力するサブルーチンを作れ。文字列の最後には0Dhが格納するものとする。
呼び出す条件として、BXには入力した文字列を格納するバッファーのアドレス、 CXには最大入力文字数-1が入っているものとし、リターン情報として、 AXレジスタに文字数(0Dhは除く)を入れ、そのほかのレジスタは保存する。
また、BS(バックスペース)も有効とする。

ヒント:
  • BSの文字コードは08hである。ただし、BSを表示しただけではカーソルが戻るだけなので、スペースを表示し、もう一度カーソルを戻す(08hを表示させる)必要がある。
  • バックスペースを有効にするために、入力した文字がすぐに表示されては困る。この場合はAH=8の状態で「INT 21h」を行うと、ALレジスタに入力された文字コードが格納される。しかしAH=2と違い、入力された文字は表示されない(C言語でいう「getch()」)。

解答
CODE	SEGMENT
	ASSUME	DS:CODE,CS:CODE,ES:CODE,SS:CODE
	.186
	ORG	100h

START:
	mov	bx,offset DATA
	mov	cx,50
	call	LINEINP

	mov	ah,2
DISP:
	mov	dl,[bx]
	int	21h		;表示
	inc	bx
	cmp	dl,0dh
	jnz	DISP

	mov	ax,4c00h
	int	21h
DATA	db	52 dup(?)	;バッファー
;+------------------------
;|1行入力
;|最後には 0Dh が入る
;+------------------------
;|in  bx <= buffer(offset)
;|    cx <= 最大文字数
;+------------------------
;|out ax <= 入力文字数
;|          (改行なし) 
;+------------------------
;|break ; ax
;+------------------------
LINEINP	proc
	push	dx
	push	di
	inc	cx
	mov	di,0
INPUT:	mov	ah,8
	int	21h

	cmp	al,8		;BSか?
	jz	_BS

	mov	[bx+di],al

	cmp	al,0dh		;リターンキーか?
	jz	_RET

	cmp	di,cx		;文字数制限大丈夫?
	jz	OVER
	inc	di

DISPC:	mov	dl,al
	mov	ah,2
	int	21h		;disp char

	jmp	short INPUT

OVER:
	mov	[di+bx-1],al	;入力可能文字数を超えていた場合の処理
	push	ax
	mov	ah,2
	mov	dl,8
	int	21h		;disp BS
	pop	ax
	jmp	short DISPC


_BS:	or	di,di
	jz	INPUT		;何も入力されていなかったらBS無効

	mov	ah,2
	mov	dl,8
	int	21h		;disp BS
	mov	ah,2
	mov	dl,' '
	int	21h		;disp SP
	mov	ah,2
	mov	dl,8		;disp BS
	int	21h
	dec	di
	jmp	short INPUT

_RET:
	mov	ah,2
	mov	dl,0dh
	int	21h
	mov	ah,2
	mov	dl,0ah
	int	21h		;改行

	mov	ax,di
	pop	di
	pop	dx
	dec	cx
	ret
	endp
	ENDS
	END	START
; 一部のコンパイラでは、
;CODE	ENDS
;	END	START
;と記述しなければいけないようです
        

←練習問題へ :  INDEX :  次の章へ→