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

汇编调用DOS中断21h获取系统时间时小时打印异常求助

问题修复:DOS中断21h获取小时后打印异常

问题出在你传递小时值给print_number过程的方式上:

DOS中断21h的2Ch功能返回的小时是8位BCD值,存在ch寄存器,但你的print_number是把整个16位cx寄存器作为输入数值处理的。你执行mov cl, ch时,只修改了cx的低8位(cl),但cx的高8位(ch)仍然保留着调用2Ch后得到的分钟值(因为你只把cl存到了temp,没改动ch)。此时cx是一个16位的组合值(旧ch的分钟 + 新cl的小时),自然会被打印成奇怪的大数(比如你看到的3084)。

而后面打印分钟和秒时正常,是因为第一次调用print_number时,过程里的xor cx, cx和loop .b会把cx清零,后续传递分钟/秒到cl时,cx的高8位已经是0,所以只会处理cl的8位值,结果正确。

两种修复方案

方案1:传递小时时清零cx的高8位

修改调用print_number打印小时的代码:

mov temp, cl

; 把小时值加载到整个cx寄存器(高8位清零)
mov cx, 0
mov cl, ch
call print_number

mov cl, temp
call print_number

mov cl, dh
call print_number
jmp exit

方案2:修改print_number只处理cl的8位值

如果你的所有待打印数值都是8位(时、分、秒都是0-59的8位值),可以直接修改print_number过程,让它只处理cl寄存器的8位内容,避免受ch的影响:

print_number proc
  push ax
  push bx
  push dx
  mov  bx, 10
  mov  al, cl  ; 仅取cl的8位数值
  xor  ah, ah  ; 将ax的高8位清零,转为16位无符号数
  xor  cx, cx       
.a:
  xor  dx, dx       
  div  bx
  add  dx, '0'
  push dx
  inc  cx
  test ax, ax
  jnz  .a
.b:
  pop  dx
  mov  ah, 02h
  int  21h
  loop .b
  mov ah, 09h
  mov dx, offset whitespace  
  int  21h
  pop  dx
  pop  bx
  pop  ax
  ret            
endp

这样不管ch寄存器里是什么值,print_number只会处理cl的8位数据,从根源上解决问题。

内容的提问来源于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 02:52:24