【发布时间】:2019-09-10 15:32:36
【问题描述】:
我在这里想要实现的是挂钩可编程间隔定时器中断(int 8)以在屏幕上显示当前时间(视频内存 0xb800),然后按一个键暂停该定时器并按相同的键恢复那个计时器。
暂时我只想让时间显示在屏幕上并让它无限期地运行(循环)。
下面是我的代码,让我解释一下我在做什么以及我面临的问题,我有子程序 DisplayUpdatedTime 调用 Int0x21 服务 0x2c 以 ch 为单位返回小时,以 cl 为单位返回分钟,以 dh 为单位返回秒,然后将小时、分钟和秒的值保存在内存变量中并调用 PrintByte。 PrintByte 子例程将 al 寄存器中的字节转换为相应的 ASCII 并在屏幕上打印。
所以我现在面临的问题是,当在 int 8 的中断例程中调用 DisplayUpdatedTime 时,会显示我的程序执行的时间,但尽管运行了一个空的无限循环,但从未更新。 (请参阅代码以了解想法),但是当我在循环中运行 DisplayUpdatedTime 子例程而不是在中断例程(int 8)中调用它时,它可以正常工作,并且我每秒都会更新计时器。
我的问题为什么我的子例程在独立循环中调用它而不是在中断服务中调用它时工作正常?
DisplayUpdatedTime:
pusha
push es
push word 0xb800
pop es
sti ;enable interrupts just in case the function is called from another
;interrupt
mov ah, 0x2c
int 0x21
xor ax,ax
mov al, ch ;place hours
mov byte [cs:Hours],al ; save the current hours
mov di,140
call PrintByte
add di,4
mov word [es:di],0x073A ;ASCII of Colon 0x3A
add di,2
mov al,cl ;place minutes
mov byte [cs:Minutes],al ; save the current Minutes
call PrintByte
add di,4
mov word [es:di],0x073A
add di,2
mov al,dh;place seconds
mov byte [cs:Seconds],al ; save the current Seconds
call PrintByte
pop es
popa
ret
;take argument in al to prints and prints at current location of di
PrintByte:
pusha
push es
push word 0xb800
pop es
mov bl,10
div bl
mov dh, 0x07
;quotient in AL, Remainder in AH
add al, 0x30 ;adding hex 30 to convert to ascii
mov dl, al
mov word [es:di],dx
add di,2
add ah,0x30
mov dl, ah
mov word [es:di],dx
mov ax,0
pop es
popa
ret`
timmerInterrupt:
push ax
call DisplayUpdatedTime
mov al,0x20 ; send EOI to PIC
out 0x20,al
pop ax
iret
这行得通
start:
l1:
call DisplayUpdatedTime
jmp l1
这不起作用为什么?
start:
xor ax,ax
mov es,ax ; point to IVT base
cli
mov word [es:8*4], timmerInterrupt ;hook int 8
mov [es:8*4+2], cs
sti
l1:
jmp l1
【问题讨论】: