最基本的字符串输入程序应该具备以下的几个功能
- 1、在输入的同时需要显示这个字符串
- 2、在输入回车符之后,字符串输入结束,也就是这个程序退出
- 3、我们用退格键可以删除字符
编写一个接收字符串输入的子程序,要实现上面三个基本功能,程序的参数有(dh)、(dl),表示显示在屏幕上的行、列的位置,以及我们让ds:si是指向字符串的存储空间,字符串以0位结尾符
思路其实就是在字符串的输入的过程当中,字符的输入和输出是按照栈的访问规则来进行的,也就是先进后出,这和栈结构是一样的,所以我们就可以去采用栈的方式来管理字符串的存储空间,也就是说字符串的存储空间实际上就是一个字符栈,字符栈中的所有字符,从栈底到栈顶组成了一个字符串
删除操作我们可以想成是字符出栈的操作,输入的操作就是字符的入栈操作,然后字符在屏幕当中显示出来其实就是显示栈当中的内容
对于下面的charpush和charpop以及charshow子程序其实需要注意的就是他们的功能分别是字符栈的入栈、出栈、显示字符栈的内容,参数ah代表的是功能号,0表示入栈,1表示出栈,2表示显示,0号功能表示的就是(al)=入栈字符,对于1号功能,(al)=返回的字符,对于2号功能:(dh)、(dl)=字符串在屏幕上显示的行和列位置
字符栈的访问如下所示
我们需要注意的就是我们每次去显示栈当中的字符的时候都要去清除屏幕上上一次显示的内容,程序中会有注释
assume cs:code,ds:data
data segment
stackdata db 128 dup (0) ;要放字符栈的数据
table dw charpush,charpop,charshow ;存放偏移地址
top dw 0
data ends
code segment
start:
;ds:si指向初始数据存放地址
mov ax,data
mov ds,ax
mov si,offset stackdata
mov dh,12
mov dl,30
call getstr ;调用程序
mov ax,4c00H
int 21H
getstr:
push ax
getstrs:
mov ah,0
int 16H
cmp al,20H
jb nochar ;如果ascii码小于20H,说明不是字符,就跳到不是字符的处理程序
mov ah,0 ;调用0号功能
call charstack ;字符入栈
mov ah,2 ;调用2号功能
call charstack ;显示栈中的字符
jmp getstrs
;输入的不是字符的情况
nochar:
cmp ah,0eH ;退格键的扫描码
je backspace
cmp ah,1cH ;Enter键的扫描码
je enter
jmp getstrs ;循环输入字符
backspace: mov ah,1
call charstack ;字符出栈
mov ah,2 ;选择调用2号功能
call charstack ;显示栈中字符
jmp getstrs
enter: mov al,0
mov ah,0
call charstack ;0入栈
mov ah,2
call charstack ;显示栈中的字符
pop ax
ret
;ah功能号,0入栈,1出栈,2显示
;ds:si指向字符空间
;对于0号功能,:(al)= 入栈字符
;对于1号功能,: (al) = 返回字符
;对于2号功能,: (dh),(dl) = 字符串在屏幕上显示的行、列位置
charstack:
jmp short charstart
;保存用到寄存器的值
charstart:push bx
push dx
push di
push es
cmp ah,2
ja sret ;如果选择的功能号大于2,则跳出子程序
mov bl,ah ;根据功能号计算处理子程序的位置并进行访问
mov bh,0
add bx,bx
jmp word ptr table[bx]
;入栈子程序
charpush: mov bx,top
mov [si][bx],al ;si指向字符空间,bx为字符相对于si的偏移地址
inc top
jmp sret
;出栈子程序
charpop:cmp top,0 ;判断栈内容是否为空,为空则结束程序
je sret
;不为空就出栈,并赋值给al
dec top
mov bx,top
mov al,[si][bx]
jmp sret
;显示字符子程序
charshow:mov bx,0b800H ;指向显存
mov es,bx
;计算显示位置
mov al,160
mov ah,0
mul dh ;结果放在axd当中
mov di,ax ;将ax给di
add dl,dl ;让列往中间靠
mov dh,0 ;给dh设置位0
add di,dx
;di中存放开始显示字符的位置
mov bx,0
charshows: cmp bx,top ;判断是否有字符要显示,top中存放要显示字符的个数
jne noempty ;有要显示的字符则转到noempty
mov byte ptr es:[di],' '
jmp sret
noempty: mov al,[si][bx] ;从栈底开始显示字符
mov es:[di],al ;每次赋值第一个先赋值,然后会把下一个将要显示的字符先清除,再显示
mov byte ptr es:[di+2],' ' ;将下一个要显示的位置清空
add di,2 ;指向下一个要显示的位置
inc bx
jmp charshows ;跳到下一次循环,显示下一个字符
sret: pop es
pop di
pop dx
pop bx
ret
code ends
end start
执行结果
点击键盘的删除键时