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

8086汇编统计零位后打印报错INT 21h, AH=09h的原因及解决方法

解决INT 21h AH=09h报错:零位数统计代码的修复

兄弟,你的统计逻辑没问题,报错完全是因为用错了DOS功能调用INT 21h AH=09h的参数规则!

报错原因拆解

先给你明确一下INT 21h AH=09h的要求:这个功能是用来打印以$结尾的字符串的,它要求DX寄存器里存放的是该字符串在内存中的偏移地址,而不是直接把ASCII码值塞进去。

你原代码里做完统计后,把零位数转成ASCII(add cx,48)就直接把cx赋值给dx去调用09h,DOS会误以为dx是内存地址,跑去那个地址开始找$结束符,结果搜了2000字节都没找到,自然就抛出那个错误了。

修复方案

我们需要先把统计得到的零位数转换成一个带$结束符的字符串,再让DX指向它的地址。具体步骤:

  1. 在.data段定义一个字节变量(或者小缓冲区)用来存数字和结束符;
  2. 把CH里的零位数(你用CH存的零计数器,CL是循环次数)转成ASCII,放到这个变量里;
  3. 调用09h时,让DX指向这个变量的偏移地址。

修改后的完整代码

.model small
.stack 100h
.data
    num db 10111111b
    itr db 8 ; 改成8更准确,因为num是8位字节,要循环8次统计所有位
    result db ? ; 用来存转换后的ASCII数字
    dollar db '$' ; 字符串结束符
.code
    mov ax, @data
    mov ds, ax

    mov cl,0 ; 循环次数计数器
    mov ch,0 ; 零位数计数器
next:
    rol num, 1
    jnc isZero
    inc cl
    cmp cl, itr
    je stop
    jmp next
isZero:
    inc ch
    inc cl ; 原代码这里漏了!不递增循环计数器会导致死循环
    jmp next
stop:
    ; 把CH里的零位数转成ASCII,存到result里
    mov al, ch
    add al, 48 ; 数字0-9转ASCII,加48即可
    mov result, al

    ; 调用INT 21h AH=09h打印字符串
    mov ah, 9
    lea dx, result ; DX指向result的偏移地址
    int 21h

    .exit
end

额外提醒

原代码里还有个隐藏坑:isZero分支里没有递增cl(循环计数器),这会导致循环永远达不到itr的次数,直接陷入死循环!我已经在修改后的代码里补上了,你可以留意一下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:03:28