程序运行时经常需要获取用户输入以完成特定功能。那么,汇编如何实现类似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