使用TASM 1.4汇编时非10字符字符串显示异常问题咨询
问题原因分析及解决思路
嘿,我之前帮不少TASM新手排查过类似问题,结合你给出的现象——输入n个字符(n<10)时,前置空格数刚好是10-n,且输出的有效字符数还不对(比如输入6个只输出2个"aa"),大概率是你的程序在缓冲区定义、输入处理和输出逻辑这几个环节出了问题,咱们逐一分析:
1. DOS输入中断的缓冲区使用错误
TASM里接收字符串最常用的是DOS中断INT 21H的0AH号功能,它要求的缓冲区有固定结构:
; 标准的输入缓冲区定义 input_buf DB 10 ; 第1字节:缓冲区最大可容纳的字符数(不含回车) DB ? ; 第2字节:实际输入的字符数(由DOS自动填充) DB 10 DUP(0) ; 第3字节开始:存储输入的字符,DOS会在末尾加回车符(0DH)
如果你错误地把缓冲区定义成了DB 10 DUP(' '),还手动把输入字符往缓冲区末尾存(比如输入n个字符就从input_buf + 10 - n的位置开始写),那前10-n个位置就会保留初始的空格,这直接导致输出时前面出现空格。再结合你输入6个只输出2个字符的情况,说明你还在输出环节搞错了循环次数或起始位置。
2. 输出逻辑的起始地址与循环计数错误
假设你用INT 21H AH=02H逐个输出字符(或用AH=09H输出带$结尾的字符串):
- 如果输出起始地址错设成了
input_buf + (10 - n) + (n - 2)(n是实际输入字符数),那输入6个时,起始地址就是input_buf + 4 + 4 = input_buf+8,而缓冲区里input_buf+2到input_buf+7是你输入的"aaaaaa",input_buf+8及以后是空格或0,这时候输出的就是最后2个字符,刚好对应你看到的"aa"。 - 另外,如果你把循环计数(比如CX寄存器)错误地设成了
n - (10 - n)(比如6-(10-6)=2),那输出时只会循环2次,自然只输出2个字符。
3. 字符串结束符处理失误
如果你的程序没正确处理输入后的回车符(0DH),或者在输出时没截断到实际输入的字符数,反而错误计算了输出长度,也会出现这种混乱的现象。比如你误把整个10字节缓冲区都输出,但又错误限制了输出次数,就会出现前置空格加部分输入字符的情况。
快速修复建议
你可以按照以下步骤排查修改:
- 先检查缓冲区定义,确保符合0AH功能的标准结构,不要自己乱改格式。
- 确认你正确读取了实际输入字符数:也就是缓冲区的第二个字节(比如
mov cl, input_buf+1),这个值才是你输入的字符总数。 - 调整输出逻辑:
- 如果用AH=02H逐个输出,起始地址应该是
input_buf+2(跳过前两个控制字节),循环次数设为实际输入的字符数(CL的值)。 - 如果用AH=09H输出字符串,要在输入字符的末尾手动加上'$',比如:
然后再调用09H输出。mov cl, input_buf+1 ; 获取实际输入字符数 lea si, input_buf+2 add si, cx mov byte ptr [si], '$' ; 在输入字符末尾加结束符
- 如果用AH=02H逐个输出,起始地址应该是
给你一段可以参考的正确输入输出示例代码:
stack segment stack dw 512 dup(?) stack ends data segment input_buf DB 10, ?, 10 DUP(0) prompt DB 'Enter a word (max 10 chars): $' data ends code segment start: mov ax, data mov ds, ax ; 显示提示信息 mov ah, 09H lea dx, prompt int 21H ; 调用DOS输入字符串功能 mov ah, 0AH lea dx, input_buf int 21H ; 输出换行 mov ah, 02H mov dl, 0AH int 21H mov dl, 0DH int 21H ; 为输出准备结束符$ mov cl, input_buf+1 lea si, input_buf+2 add si, cx mov byte ptr [si], '$' ; 输出输入的字符串 mov ah, 09H lea dx, input_buf+2 int 21H ; 退出程序 mov ah, 4CH int 21H code ends end start
你可以对比这段代码,看看自己的程序哪里逻辑走偏了,重点关注输入后的字符处理和输出的起始位置、循环计数部分。
内容的提问来源于stack exchange,提问作者Lawrence
相关产品推荐
相关产品推荐

