汇编程序无法读取超10字符、输出两位数位置的问题求助
汇编程序修改方案:支持长输入与两位数位置输出
问题原因
- 输入长度限制误解:你当前的输入缓冲区定义完全符合DOS
int 21h0Ah功能要求,理论上支持最多254个字符输入。你误以为无法读取超过10个字符,大概率是因为第二个问题(两位数位置输出错误)导致的视觉混淆。 - 两位数位置输出错误:原代码中直接将
count(位置值)加'0'转ASCII,仅适用于0-9的数字。当位置≥10时,count是两位数,这种方式会输出错误的ASCII字符(比如10会输出:),无法正确显示两位数。
解决思路
- 新增数字转ASCII输出子程序:处理0-255范围内的整数,拆分十位、个位分别转ASCII后输出。
- 优化位置输出格式:添加空格分隔多个位置,提升可读性。
- 可选:将
count改为16位变量,避免后续扩展时的溢出风险(虽然8位已足够处理255以内的位置)。
修改后的完整代码
.model small .stack 100h .data buf db 255 ; 最大输入字符数(不含回车) howMany db ? ; 实际输入字符数(由系统填充) char db 255 dup (?) ; 输入字符存储区 msgIvesti db "Iveskite eilute:", 10, 13, "$" msgRezult db "Rezultatai:",10,13,"$" count dw 0 ; 改用16位变量存储位置 space db " $" ; 位置分隔空格 .code Start: mov ax, @data mov ds, ax ; 显示输入提示 mov ah, 9 mov dx, OFFSET msgIvesti int 21h ; 读取输入字符串 mov ah, 0Ah mov dx,OFFSET buf int 21h ; 显示结果提示 mov ah, 9 mov dx,OFFSET msgRezult int 21h mov cl, howMany mov ch, 0 ; CX = 实际输入字符数 mov si, OFFSET char cycle: lodsb inc count ; 位置从1开始计数 cmp al,'0' jb notDigit cmp al, '9' ja notDigit ; 输出当前数字的位置 mov ax, count call PrintNumber ; 输出分隔空格 mov ah, 9 mov dx, OFFSET space int 21h notDigit: dec cl cmp cl, 0 jne cycle endi: mov ax, 4C00h int 21h ; 子程序:输出AX中的十进制数(0-255) PrintNumber: push bx push cx push dx mov cx, 0 ; 记录数字位数 mov bx, 10 ; 除数为10 DivideLoop: xor dx, dx ; DX清零,DIV使用DX:AX作为被除数 div bx ; AX = 商,DX = 余数(当前位数字) push dx ; 保存余数 inc cx ; 位数+1 cmp ax, 0 ; 商为0时结束除法 jne DivideLoop OutputLoop: pop dx ; 取出余数 add dl, '0' ; 转为ASCII字符 mov ah, 02h int 21h loop OutputLoop pop dx pop cx pop bx ret END Start
关键修改说明
count变量类型调整:从db改为dw,虽然8位变量足够处理255以内的位置,但16位变量更灵活,避免后续扩展时的溢出问题。PrintNumber子程序:通过除法拆分数字的每一位,将余数入栈后反向取出输出,实现正确的十进制数字转ASCII输出,支持两位数甚至三位数(如255)。- 添加分隔空格:每个位置后输出空格,让多个位置的结果更清晰(例如输入
abc123xyz456会输出4 5 6 10 11 12)。 - 输入部分验证:原输入缓冲区定义完全正确,
buf的第一个字节设为255,意味着最多可以输入254个字符,不存在10个字符的限制。
内容的提问来源于stack exchange,提问作者raidija
相关产品推荐
相关产品推荐

