程序運行時經常需要獲取用戶輸入以完成特定功能。那麼,彙編如何實現類似C語言的fgets函數(在命令行下輸入字符串,按回車即給某變量賦值)功能呢?貌似沒有現成的中斷可以調用!但這又是經常要用到的功能,所以我特地花了點時間完成了這項功能,其中包含三個功能函數(相對獨立,可單獨使用):
1.newline:實現換行功能。如行號小於24則簡單的換行,如大於24則能自動上卷屏幕;
2.get_str:獲取用戶輸入。實現用戶輸入顯示,撤消,按回車後自動給變量賦值,並自動換行。並且實現輸入長度控制(由cx傳遞字符串最大長度);
3.showstr:顯示一個以0結尾的字符串,並自動將光標置於最後一個字符後;
效果圖如下:
以下是代碼部分:
;換行(當前行的下一行)
newline:
push ax
push bx
push cx
push dx
;獲得當前頁光標信息
;出口參數:
;CH=光標的起始行
;CL=光標的終止行
;DH=行(Y座標)
;DL=列(X座標)
mov ah,03h
mov bh,0
int 10h
;如果當前行號小於24則不用上卷
cmp dh,24
jb incrow
;上滾一行
;參數
;AL = 上卷行數
;AL =0全屏幕爲空白
;BH = 捲入行屬性
;CH = 左上角行號
;CL = 左上角列號
;DH = 右下角行號
;DL = 右下角列號
mov ah,06h
mov al,1
mov bh,07h
mov ch,0
mov cl,0
mov dh,24
mov dl,80
int 10h
jmp changerow
incrow: inc dh
changerow:
mov ah,2
mov bh,0
mov dl,0
int 10h
nrtn:
pop dx
pop cx
pop bx
pop ax
ret
;在當前行顯示字符串(80*25)
;@param ds:si - 變量地址
;@param cx - 變量長度
showstr:
push ax
push bx
push cx
push dx
push es
push di
push si
push cx
;獲得當前頁光標信息
;出口參數:
;CH=光標的起始行
;CL=光標的終止行
;DH=行(Y座標)
;DL=列(X座標)
mov ah,03h
mov bh,0
int 10h
pop cx
;獲得顯存中當前行的位置
mov ax,0b800h
mov es,ax
mov al,160
mul dh
mov di,ax
;清空並顯示當前行
mov bx,0
mov dl,0
s: mov al,ds:[si]
cmp al,0
jne _if
mov byte ptr es:[bx+di],' '
jmp short _endif
_if: mov byte ptr es:[bx+di],al
inc dl
_endif: inc si
add bx,2
loop s
;設置光標位置
mov ah,2
mov bh,0
int 10h
pop si
pop di
pop es
pop dx
pop cx
pop bx
pop ax
ret
;獲取用戶輸入
;@param ds:si - 變量地址
;@param cx - 變量長度
get_str:
push ax
push bx
push cx
push dx
push si
;記錄變量起始地址
mov bx,si
;已經輸入的字符串長度
mov dx,0
;初始化變量
push cx
push si
s1:
mov byte ptr ds:[si],0
inc si
loop s1
pop si
pop cx
;循環獲取用戶輸入
get:
mov ah,0
int 16h
;如果是換行
cmp ah,1ch
je gtrn
;如果是退格
cmp ah,0eh
je delchar
;如果達到變量長度,則什麼都不做
cmp dx,cx
jnb get
;如果是普通字符
mov byte ptr ds:[si],al
inc si
inc dx
jmp gshowstr
delchar:
cmp si,bx
jna get
dec si
dec dx
mov byte ptr ds:[si],0
jmp gshowstr
gshowstr:
push si
mov si,bx
call showstr
pop si
jmp get
gtrn:
call newline
pop si
pop dx
pop cx
pop bx
pop ax
ret