Dos 汇编程序在中断期间挂起

Dos Assembly Program hanging during Interrupt

以下程序在没有错误或警告的情况下进行汇编。但是,当我 运行 它在顶部显示 "ABK" 然后挂起 DosBox。 我正在使用 nasm 汇编程序和 DosBox。 我写

nasm eex9_2.asm -o eex9_2.com

        [org 0x100]

        jmp start

oldisr: dd 0
kbisr:  push ax
        push es
        mov ax, 0xb800
        mov es, ax

        xor ax, ax

        in al, 0x60
        mov byte [es:0], 'A'
        mov byte [es:2], 'B'
        mov byte [es:4], 'K'

        mov al, 0x20
        out 0x20, al

        pop es
        pop ax
        iret

start:  xor  ax, ax
        mov  es, ax
        mov  ax, [es:9*4]
        mov  [oldisr], ax
        mov  ax, [es:9*4+2]
        mov  [oldisr+2], ax

        mov  word [es:9*4], kbisr ; store offset at n*4
        mov  [es:9*4+2], cs


        mov dx, start
        add dx, 6
        mov cl, 4
        shr dx, cl
        mov ax, 0x3100
        int 21h

你的程序有两个问题:

更小的一个是下面两行:

mov  word [es:9*4], kbisr
mov  [es:9*4+2], cs

如果在两条指令的第一条指令之后接收到一些键盘输入,系统将崩溃,因为中断处理程序地址错误(它是 "old" 段和 "new" 偏移量)。

您应该执行以下操作:

cli
mov  word [es:9*4], kbisr
mov  [es:9*4+2], cs
sti

然而,主要问题 是 Michael Petch 所写的问题:

操作系统使用中断获取键盘输入。如果您键入:

C:\>dir

中断将被调用8次:

  • 按下"D"一次
  • 释放"D"时一次
  • ...
  • 释放 return 键时一次

每次按下一个键时,中断都会读取键数据(就像您的中断所做的那样)并将数据写入内存。操作系统(或其他程序)会读出内存中的数据,就知道你输入了"dir".

如果您安装自己的键盘中断,则不会有数据写入该内存(除非您的中断这样做),因此没有程序可以再读取键盘!

如果您对来自键盘的数据(实际按下的键)不感兴趣,您可以按照 Michael Petch 的建议进行操作:

kbisr:  push ax
        push es
        mov ax, 0xb800
        mov es, ax
        mov byte [es:0], 'A'
        mov byte [es:2], 'B'
        mov byte [es:4], 'K'
        pop es
        pop ax
        jmp far [cs:oldisr]

(我不确定最后一行的语法是否正确,因为我使用的 GNU 汇编器使用的语法不同于 nasm。)

最后一行将跳转到原始中断,它将执行...

  • ...端口0x60的读取
  • ... 将 0x20 写入端口 0x20
  • ...将键盘数据写入内存(你不会做的)
  • ... IRET

如果您需要知道按下了哪个键并且您希望 OS 正常工作,您几乎没有机会...