汇编调用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
相关产品推荐
相关产品推荐

