8086汇编中字符串输入后无法重复输出的问题排查
问题分析与解决
你的汇编程序仅打印一次输入字符串的问题,根源在于DOS中断INT 21h的0Ah(字符输入)和09h(字符串输出)功能的使用不符合规范,具体原因如下:
1. 缓冲区格式不符合0Ah功能要求
INT 21h的0Ah功能(带缓冲的键盘输入)对缓冲区结构有严格要求:
- 第1字节:缓冲区的最大容量(允许输入的字符总数,包括最后的回车符)
- 第2字节:输入完成后,系统会自动填入实际输入的字符数(不包含回车)
- 从第3字节开始:存储用户输入的字符,最后会自动追加一个回车符(0Dh)
你定义的buffer db 8 dup("$")完全不符合这个结构,会导致输入操作时内存读写混乱,后续输出逻辑也会出错。
2. 输入字符串缺少09h要求的$终止符
INT 21h的09h功能要求输出的字符串必须以$结尾才会停止输出。但0Ah输入的字符串末尾是回车符(0Dh),没有自动添加$,这会导致两种问题:
- 09h输出时会持续读取内存,直到遇到随机存在的
$,可能输出乱码 - 回车符会让光标回到当前行开头,第二次输出时直接覆盖第一次的内容,看起来像是只打印了一次
修正后的代码
.model small .stack 100h .data ; 缓冲区结构: ; 第1字节:最大允许输入字符数(含回车,这里设为7=6个可见字符+1回车) ; 第2字节:实际输入字符数(系统填充) ; 第3-9字节:存储输入字符+回车,预留位置加$终止符 buffer db 7, 0, 7 dup("$") .code main proc mov ax,@data mov ds,ax ; 调用0Ah读取用户输入 LEA dx,buffer mov ah,0Ah int 21h ; 在输入字符串末尾添加$终止符 mov cl, buffer[1] ; 取实际输入的字符数 mov ch, 0 mov bx, cx mov buffer[bx+2], "$" ; 在回车符后插入$ ; 第一次输出输入的字符串(跳过前两个控制字节) LEA dx,buffer+2 mov ah,09h int 21h ; 添加换行+回车,避免第二次输出覆盖 mov dl, 0Ah mov ah, 02h int 21h mov dl, 0Dh mov ah, 02h int 21h ; 第二次输出 LEA dx,buffer+2 mov ah,09h int 21h ; 程序退出 mov ah,4ch int 21h main endp end main
关键修正点
- 按照0Ah的规范定义缓冲区,确保输入操作正常执行
- 输入完成后手动添加
$终止符,让09h能正确识别字符串结束位置 - 输出时跳过缓冲区的前两个控制字节,直接指向用户输入的字符
- 两次输出之间添加换行和回车,避免内容覆盖
内容的提问来源于stack exchange,提问作者Ashutosh Deshmukh
相关产品推荐
相关产品推荐

