使用mov ah,2与int 1ah打印系统时间时小时输出错误如何修复?
问题修复方案
存在的两处核心bug
time子程序末尾的ret返回指令被注释,调用完获取时间的中断后无法正确返回调用点,会直接顺次执行后续代码,属于严重逻辑错误。cvthrs小时转换子程序中,提取BCD码低位的and bh,0fh指令被注释,导致小时的低位数值没有屏蔽高4位,BCD转ASCII时计算结果错误,这是小时字段输出异常的直接原因。
另外原有代码缺少引导扇区签名,部分BIOS/模拟器可能无法识别为可引导介质,修复时也会补充该部分。
修复后完整代码
BITS 16 ORG 0x7C00 _start: mov ax, 07C0h add ax, 288 mov ss, ax ; ss = stack space mov sp, 4096 ; sp = stack pointer mov ax, 07C0h mov ds, ax ; ds = data segment call time call cvthrs call cvtmin call cvtsec call dsptime cli endloop: hlt jmp endloop time: ;Get time from the system mov ah,02h int 1Ah ret ; 恢复返回指令 ;CH - Hours ;CL - Minutes ;DH - Seconds cvthrs: ;Converts the system time from BCD to ASCII mov bh,ch ;copy contents of hours (ch) to bh shr bh, 4 add bh,30h ;add 30h to convert to ascii mov [tmfld],bh mov bh,ch and bh,0fh ; 恢复BCD低位提取逻辑 add bh,30h mov [tmfld + 1],bh ret cvtmin: mov bh,cl ;copy contents of minutes (cl) to bh shr bh, 4 add bh,30h ;add 30h to convert to ascii mov [tmfld + 3],bh mov bh,cl and bh,0fh add bh,30h mov [tmfld + 4],bh ret cvtsec: mov bh,dh ;copy contents of seconds (dh) to bh shr bh, 4 add bh,30h ;add 30h to convert to ascii mov [tmfld + 6],bh mov bh,dh and bh,0fh add bh,30h mov [tmfld + 7],bh ret tmfld: db '00:00:00' dsptime: ;Display the system time mov ah,13h ;function 13h (Display String) mov al,0 ;Write mode is zero mov bh,0 ;Use video page of zero mov bl,0x0f;Attribute mov cx,8 ;Character string is 8 long mov dh,5 ;position on row 5 mov dl,0;and column 0 push ds ;put ds register on stack pop es ;pop it into es register lea bp,[tmfld] ;load the offset address of string into BP int 10H ret ; 补充引导扇区签名 times 510 - ($ - $$) db 0 dw 0xAA55
编译运行
使用原有命令即可正常执行:
nasm time.asm -fbin -o time.img qemu-system-i386 -drive format=raw,file=./time.img
内容的提问来源于stack exchange,提问作者nornor
相关产品推荐
相关产品推荐

