我怎样才能在不使用DOS中断的情况下获得时间?
ubbxdtey1#
不使用中断从DOS获取时间如果您不想使用DOS.GetSystemTime函数2Ch(int 21h),则始终存在BIOS.GetRealTimeClockTime函数02h(int 1Ah)。这两个函数都以CH格式返回小时,以CL格式返回分钟,以DH格式返回秒但是与返回整数的DOS不同,BIOS以BCD格式返回数字。
int 21h
int 1Ah
23:17:45 DOS vs BIOS -------------------------- CH=23 (17h) CH=35 (23h) CL=17 (11h) CH=23 (17h) DH=45 (2Dh) CH=69 (45h)
如果你不想使用上面提到的任何一个函数,那么一个足够接近的近似值来自于阅读BIOS。TimerTick保存在内存地址046Ch(dword)。由于简化的数学,一天的第一分钟(并且只有第一分钟)将花费大约70秒。如果你的程序不显示秒,用户甚至不会注意到这一点。
; -> CH is hours [0,23] ; -> CL is minutes [0,59] ; IN () OUT (cx) GetTime: cli push ds push ax push dx xor cx, cx ; 00:00 mov ds, cx mov al, byte ptr [046Ch + 2] ; [0,24] cmp al, 24 je .OK mov ch, al ; Hours [0,23] mov ax, 60 mul word ptr [046Ch] mov cl, dl ; Minutes [0,59] .OK: pop dx pop ax pop ds sti ret
为了验证,我编写了下一个程序,它在控制台上以hh:mm:ss格式显示当前时间:
ORG 256 ; Creating a .COM program mov bh, -1 ; LastKnownSeconds Main: call GetTime ; -> CH CL DH DL=0 cmp dh, bh je Main ; Seconds didn't change mov bh, dh mov bl, ':' mov al, ch ; Hours call PrintTrio ; -> (AX DX) mov al, cl ; Minutes call PrintTrio ; -> (AX DX) mov bl, 13 mov al, bh ; Seconds call PrintTrio ; -> (AX DX) mov dl, 10 mov ah, 02h ; DOS.PrintCharacter int 21h mov ah, 01h ; BIOS.CheckKeystroke int 16h ; -> AX ZF jz Main ; No key waiting mov ah, 00h ; BIOS.GetKeystroke int 16h ; -> AX ret ; TerminateProgram ; ---------------------------- ; IN (al,bl) OUT () MOD (ax,dx) PrintTrio: aam ; -> AH = AL / 10, AL = AL % 10 add ax, '00' ; Convert to ASCII push ax ; (1) mov dl, ah mov ah, 02h ; DOS.PrintCharacter int 21h pop dx ; (1) mov ah, 02h ; DOS.PrintCharacter int 21h mov dl, bl mov ah, 02h ; DOS.PrintCharacter int 21h ret ; ---------------------------- ; IN () OUT (ch,cl,dh,dl=0) GetTime: push ds push ax push bx xor dx, dx ; 00:00:00 xor cx, cx mov ds, cx cli mov ax, word ptr [046Ch] ; BIOS.TimerTick mov bx, word ptr [046Ch+2] ; [0,24] sti cmp bl, 24 je .OK mov ch, bl ; Hours [0,23] mov bl, 60 ; BH=0 mul bx mov cl, dl ; Minutes [0,59] mul bx mov dh, dl ; Seconds [0,59] mov dl, 0 .OK: pop bx pop ax pop ds ret ; ----------------------------
1条答案
按热度按时间ubbxdtey1#
不使用中断从DOS获取时间
如果您不想使用DOS.GetSystemTime函数2Ch(
int 21h
),则始终存在BIOS.GetRealTimeClockTime函数02h(int 1Ah
)。这两个函数都以CH格式返回小时,以CL格式返回分钟,以DH格式返回秒但是与返回整数的DOS不同,BIOS以BCD格式返回数字。如果你不想使用上面提到的任何一个函数,那么一个足够接近的近似值来自于阅读BIOS。TimerTick保存在内存地址046Ch(dword)。由于简化的数学,一天的第一分钟(并且只有第一分钟)将花费大约70秒。如果你的程序不显示秒,用户甚至不会注意到这一点。
为了验证,我编写了下一个程序,它在控制台上以hh:mm:ss格式显示当前时间: