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