鱼C论坛

 找回密码
 立即注册
查看: 2590|回复: 0

[技术交流] 汇编17.3 字符串的输入

[复制链接]
发表于 2020-9-21 16:46:31 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 sbx 于 2020-9-22 10:13 编辑

最基本的字符串输入程序,需要具备下面的功能。:
--(1) 在输入的同时需要显示这个字符串;
--(2) 一般在输入回车符后,字符串输入结束;
--(3) 能够删除已经输入的字符。
对于这三个功能,我们可以想象在DOS中,输入命令行时的情况。

编写一个接收字符串的输入子程序,实现上面三个基本功能。因为在输入的过程中需要显示,子程序的参数如下:
--(dh)、(dl)=字符串在屏幕上显示的行、列位置;
--ds:si指向字符串的存储空间,字符串以0为结尾符。
下面我们将进行仔细分析!
(1) 字符的输入和删除。
每个新输入的字符都存储在前一个输入的字符之后,而删除是从最后面的字符进行的。
我们看下面的过程:
空字符串:
输入“a”:a
输入“b”:ab
输入“c”:abc
输入“d”:abcd
删除一个字符:abc
删除一个字符:ab
删除一个字符:a
删除一个字符:
可以看出在字符串输入的过程中,字符的输入和输出是按照栈的访问规则进行的,即后进先出。

这样,我们就可以用栈的方式来管理字符串的存储空间,也就是说,字符串的存储空间实际上是一个字符栈。
字符栈中的所有字符,从栈底到栈顶,组成一个字符串。
(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 128 dup (0)
data ends
code segment
start:mov ax, data
mov ds, ax
mov si, 0        ;将ds:si设为存放字符的栈
mov dh,12             ;设置行为第12行
mov dl,32             ;设置列为第32列
call getstr

return:
mov ax,4c00h
int 21h

;完整的接收字符串输入的子程序

getstr:
push ax

getstrs:
mov ah,0
int 16h

cmp al,20h
jb nochar    ;判断的是ASCII码小于0,说明不是字符。
mov ah,0
call charstack  ;字符入栈
mov ah,2
call charstack  ;显示栈中的字符
jmp getstrs

nochar:
cmp ah,0eh      ;退格键的扫描码
je backspace
cmp ah,1ch      ;回车键的扫描码
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              ;getstr ends

;功能子程序实现

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

code ends
end start


截图未命名18.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 12:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表