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

汇编开发求助:无法正确打印系统计时器寄存器的8位数值

如何正确打印DOS系统计时器返回的8位日期数值

问题根源分析

你的代码里8位数值打印错误的核心原因是误用了16位除法指令:

  • div si是16位除法操作,会把AX寄存器整体作为被除数,但你只给AL或AH赋值了目标8位数值,另一个8位寄存器里残留着之前程序运行的垃圾值,导致被除数远大于实际要打印的数值,最终输出异常。
  • 比如print_number8bith中,你把月份(DH)放到AH,但AL还是之前打印年份时残留的值,此时AX是一个随机的16位数,除以10后自然得到错误结果。

修正方案

只需要写一个通用的8位数值打印函数,使用8位除法指令来处理,避免16位寄存器的干扰:

  1. 把要打印的8位数值放到AL寄存器
  2. 用div bl(8位除法)来做十进制拆分,拆分前先清零AH(避免余数干扰)
  3. 把余数转成ASCII后入栈,最后依次弹出打印

修正后的完整代码

SSEG    segment stack       
        db 256 dup(0)
SSEG    ends

DSEG    segment         
   whitespace db ' $'
DSEG    ends

CSEG    segment         
        assume cs:CSEG,ds:DSEG,ss:SSEG
begin:
        mov ax, DSEG    
        mov ds, ax   

    ; 调用DOS中断2Ah获取系统日期
    mov ah, 2Ah
    int 21h
    
    ; 打印年份(CX寄存器,16位)
    mov bx, cx
    call print_number16bit
    
    ; 打印月份(DH寄存器,8位)
    mov al, dh
    call print_number8bit
    
    ; 打印日期(DL寄存器,8位)
    mov al, dl
    call print_number8bit
    
    ; 打印星期(AL寄存器,8位,中断返回后直接可用)
    call print_number8bit
    
    ; 等待按键
    mov ah,01h    
    int 21h         

    ; 程序退出
    mov ah,4ch      
    int 21h         

; 打印16位数值(参数:BX寄存器存要打印的数值)
print_number16bit proc
       mov si,10
       mov ax,bx
       mov cx,0
    a1:
       mov dx,0
       div si
       add dx,'0'
       push dx
       inc cx
       cmp ax,0
       jnz a1
    aa1:
       pop dx
       mov ah,02h
       int 21h
       loop aa1
       
       mov ah, 09h
       mov dx, offset whitespace
       int 21h
    ret
endp

; 打印8位数值(参数:AL寄存器存要打印的数值)
print_number8bit proc
       mov bl, 10       ; 除数设为10
       mov cx, 0
    a2:
       xor ah, ah       ; 清零AH,确保8位除法的被除数只有AL里的数值
       div bl           ; AL = 商,AH = 余数
       add ah, '0'      ; 余数转ASCII字符
       push ax          ; 将余数(存在AH)入栈保存
       inc cx
       cmp al, 0
       jnz a2
    aa2:
       pop ax
       mov dl, ah       ; 取出栈中的余数
       mov ah, 02h
       int 21h
       loop aa2
       
       ; 打印分隔空格
       mov ah, 09h
       mov dx, offset whitespace
       int 21h
    ret
endp

CSEG    ends        

end begin   

关键修改说明

  • 合并了原来的print_number8bitl和print_number8bith为一个通用的print_number8bit函数,减少冗余代码
  • 使用div bl(8位除法)替代div si,仅用AL作为被除数,提前清零AH避免干扰
  • 主程序中直接把8位寄存器(DH、DL、AL)的值放到AL后调用函数,参数传递更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:53:13