Warm tip: This article is reproduced from serverfault.com, please click

assembly-为什么 BIOS 中断 8(计时器)在 qemu-system-x86_64 上不起作用

(assembly - Why BIOS interrupt 8 (timer) not working on qemu-system-x86_64)

发布于 2021-01-06 08:59:00

我想 BIOS 中断 8(计时器)应该每秒出现 18.2 次,但在 qemu 上没有。请参阅以下示例:

$ cat c.asm

init:
    .segments:
        mov ax, 0x07C0
        mov ds, ax
        mov ax, 0
        mov fs, ax
    .interrupt:
        mov [fs:0x08*4], word timer
        mov [fs:0x08*4+2], ds

main:
    hlt
    jmp main

timer:
    mov ah, 0x0e
    mov al, 0x41
    int 0x10
    iret

times 510-($-$$) db 0
dw 0xaa55
$ nasm -f bin c.asm -o c.bin && qemu-system-x86_64 c.bin

出现 Qemu 窗口,只显示一个“A”,而不是连续显示。

我的代码有什么问题,如果我希望一次又一次地中断8次。

我使用 nasm 1.14.02、qemu 4.2.1 和 ubuntu 20.04。

Questioner
L. Ouyang
Viewed
0
ecm 2021-01-06 22:19:06

使其重复显示“A”的关键更改是在端口 20h 上向 PIC 发送中断结束信号。如果你使用中断 1Ch 或链接到另一个中断 08h 处理程序,则你的代码中不需要它。如果你完全替换中断 08h 处理程序,它是。PIC 不会发送另一个 IRQ #0,直到前一个收到 EOI。因此,我能够重现你的问题。

我所做的其他更改是确保在进入main循环(使用sti指令)之前设置中断标志,并保留中断 08h 处理程序中的所有寄存器(如果你的代码是机器上唯一运行的代码,则这是可选的)。

init:
    .segments:
        mov ax, 0x07C0
        mov ds, ax
        mov ax, 0
        mov fs, ax
    .interrupt:
        mov [fs:0x08*4], word timer
        mov [fs:0x08*4+2], ds

        sti
main:
    hlt
    jmp main

timer:
        push ax
        push bx
        push bp
    mov ah, 0x0e
    mov al, 0x41
    int 0x10
        mov al, 20h
        out 20h, al
        pop bp
        pop bx
        pop ax
    iret

times 510-($-$$) db 0
dw 0xaa55

像这样运行:

$ nasm test.asm
$ timeout 10 qemu-system-x86_64 test -curses