最基本的字符串输入程序通常具备以下功能
(1)在输入的同时要显示输入的字符串
(2)在输入回车符后,字符串输入结束
(3)能删除已输入的字符
分析如下:
(1)我们知道字符串的输入和删除是以栈的访问规则进行的,即后进先出,因此我们可以用栈的方式来管理字符串的存储空间
(2)输入回车符后可以在字符串中加入0,表示字符串结束
(3)每次重新输入一个字符或者删除一个字符,都要重新显示字符串,即从栈底到栈顶显示所有字符串
(4)程序处理逻辑如下:
- ①我们可以调用int 16h读入键盘输入
- ②如果是字符就进入字符栈,显示所有字符,继续执行①
- ③如果是退格键,从字符栈中弹出一个字符,显示所有字符,继续执行①
- ④如果是Enter键,向字符栈中压入0,返回
从程序的处理过程可以看出,字符栈的入栈、出栈、显示是需要频繁调用的,因此将它们写为子程序
;子程序:字符串的入栈、出栈、显示
;参数说明:(ah)=功能号,0表示入栈,1表示出栈,2表示显示
; ds:si指向字符栈空间
; 对于0号功能:(al)=入栈字符
; 对于1号功能:(al)=出栈字符
; 对于2号功能:(dh)、(dl)表示屏幕上的行和列
assume cs:code, ds:data
data segment
db 10 dup (0)
data ends
code segment
start:mov ax, data
mov ds, ax
mov si, 0 ;将ds:di设为存放字符的栈
mov ah, 2
mov dh, 0
mov dl, 0
call getstr
mov ax, 4c00h
int 21h
charstack:jmp short charstart
table dw charpush, charpop, charshow
top dw 0 ;栈顶
charstart:push bx
push dx
push di
push es
cmp ah, 2
ja sret
mov bl, ah
mov bh, 0
add bx, bx
jmp word ptr table[bx]
charpush:mov bx, top
mov [si][bx], al
inc top
jmp sret
charpop:cmp top, 0
je sret
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
mov di, ax ;行
add dl, dl ;列
mov dh, 0
add di, dx ;屏幕字节索引
mov bx, 0 ;初始化为0用于和字符串结束标志做对比
charshows:cmp bx, top
jne noempty
mov byte ptr es:[di], ' ' ;输入空格符
jmp sret
noempty:mov al, [si][bx]
mov es:[di], al
mov byte ptr es:[di + 2], ' ' ;将屏幕当前行列的下一个字符置空,等待下一次输入
inc bx
add di, 2
jmp charshows
sret: pop es
pop di
pop dx
pop bx
ret
;循环读取键盘缓冲区的字符
getstr:push ax
getstrs:mov ah, 0
int 16h
cmp al, 20h
jb nochar ;ASCII码小于20h,说明不是字符
;入栈并显示字符
mov ah, 0
call charstack ;字符入栈
mov ah, 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
call charstack ;显示栈中的字符
jmp getstrs
enter:mov al, 0
mov ah, 0
call charstack ;0入栈
mov ah, 2
call charstack ;显示栈中的字符
pop ax
ret
code ends
end start
程序执行结果:
程序中显示字符串的子程序,也可以不必在入栈或出栈子程序调用之后再调用,可以直接放到入栈和出栈的子程序中调用,只有当字符栈内容发生变化才会调用显示字符串的功能,因此可将显示功能集成到出栈和入栈子程序中,更为方便!