You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用int 16h中断读取多位十进制数出错:仅存0值求助

问题分析与解决方案

核心错误点

  1. 无效标签跳转:代码中使用了未定义的.LeeTecla标签,输入非数字字符时程序会跳转到未知内存区域,破坏寄存器状态,导致累加器BX值异常。需将.LeeTecla改为循环入口标签.ReadKey。
  2. 累加逻辑完全颠倒:当前代码错误地将单个输入数字乘以10后加到累加器,而正确逻辑应为累加器先乘以10,再加上单个输入数字。例如输入12时,错误逻辑会计算为0+1*10=10 → 10+2*10=30,完全偏离预期结果。

修正后的代码

ReadDecimalNumber16h proc
 push ax
 push bx
 push cx
 push dx

    xor bx, bx ; BX = 累加器初始化为0

.ReadKey:
 mov ah, 00h
 int 16h ; 读取按键,AL=ASCII码,AH=扫描码

    cmp al, 13 ; 检测回车键
 je .EndRead ; 按下回车则结束读取

    ; 回显输入字符
 mov ah, 0Eh
 int 10h

    ; 可选:处理退格键(提升输入体验)
 cmp al, 8
 je .HandleBackspace

    ; 验证输入是否为数字'0'~'9'
 cmp al, '0'
 jb .ReadKey ; 非数字,忽略
 cmp al, '9'
 ja .ReadKey ; 非数字,忽略

    ; 将ASCII字符转换为数值
 sub al, '0' ; AL = 0-9的数值
 xor ah, ah ; AX = 单个数字值

    ; 正确执行累加:BX = BX * 10 + AX
 push ax ; 暂存当前数字
 mov ax, bx ; AX = 当前累加值
 mov cx, 10
 mul cx ; AX = 累加值 * 10(16位范围内无溢出时DX=0)
 mov bx, ax ; 更新累加器为原数值的10倍
 pop ax ; 取出暂存的单个数字
 add bx, ax ; 累加器加上当前数字

    jmp .ReadKey

; 退格处理逻辑(可选)
.HandleBackspace:
 mov ax, bx
 mov cx, 10
 xor dx, dx
 div cx ; AX = BX / 10(删除最后一位),DX=余数(丢弃)
 mov bx, ax
 ; 屏幕上删除字符:左移光标→空格覆盖→左移光标
 mov ah, 0Eh
 mov al, 8
 int 10h
 mov al, ' '
 int 10h
 mov al, 8
 int 10h
 jmp .ReadKey

.EndRead:
 mov ax, bx ; 最终结果存入AX返回

    pop dx
 pop cx
 pop bx
 pop ax
 ret
ReadDecimalNumber16h endp

针对int 16h中断的优化建议

  • 退格功能:如上代码中添加的.HandleBackspace分支,允许用户删除错误输入,提升交互友好性。
  • 溢出防护:16位寄存器BX最大可存储十进制数65535,在执行mul cx前可判断BX > 6553(因为6553*10+9=65539超过16位上限),若超出则拒绝输入并提示溢出。
  • 功能键过滤:利用int 16h返回的AH扫描码,过滤方向键、功能键等非输入键,避免无效字符干扰。
  • 输入提示:调用该过程前可输出提示文本(如"请输入分子:"),明确用户输入要求。

内容的提问来源于stack exchange,提问作者Serujio74

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:43:11