0

我试图在按下一个键时覆盖默认中断。这是我的代码:我不明白为什么它不起作用,它适用于其他 INT 数字(例如 43h)

mov al,9h
mov ah,25h
mov bx,seg int9h
mov ds,bx
mov dx,offset int9h
int 21h

(其中 int9h 是我的代码中的标签)有谁知道按下键时如何挂断中断?谢谢 !

编辑:

mov     ax,2509h
mov     dx,offset int9h
int     21h            

int9h PROC
    ;do some stuff
    IRET 
int9h ENDP
4

2 回答 2

2

我将尝试再次回答这个问题 - 以一种有点冗长的方式。

在 Windows 流行之前,DOS 统治着计算机。为了扩展其功能,人们曾经编写过 TSR(terminate and stay resident)程序;这些程序将挂钩各种中断功能(例如时钟和键盘),终止然后驻留在内存中。结果,当给定中断发生时,这些实用程序的驻留代码将处理中断,可能会调用原始中断处理程序。

此类程序将具有由两部分组成的结构:临时部分和常驻部分。瞬态部分是从命令行调用程序时运行的代码;这将检查驻留部分是否已经安装。如果已经安装了常驻部分,程序将直接退出,但如果这是第一次调用,程序将首先保存当前中断处理程序的地址,然后安装自己的代码作为新的中断处理程序,然后进行特殊处理将处理程序代码留在内存中的 DOS 调用。

您显示的代码是临时程序的一部分,其中新的中断处理程序安装到中断表中。这段代码应该只运行一次,并且肯定不是新中断处理程序本身的一部分。

当 Windows 的使用变得广泛时,TSR 程序就过时了。从某种意义上说,在 Windows 下运行的每个程序都是 TSR 程序,而键盘中断处理程序代码现在变成了在“OnKeyPress”函数中处理的键盘事件(例如在 Delphi 中)。

以下代码更改中断表

mov ax, 2509h
mov dx, offset kb_handler
int 21h

从地址 *kb_handler* 开始的代码是实际的中断处理程序。

您正在做的是重复设置中断处理程序的地址,而不是处理中断。安装程序本身时,您的上述代码应该只运行一次;中断处理程序代码将被多次调用。

我希望这能让事情变得更清楚。

你没有写的是你为什么要这样做

于 2012-10-15T05:33:48.373 回答
1

我从我的档案中挖出了以下代码(日期为 1995 年 6 月 24 日);这是我编写的一个程序的键盘处理程序,如果同时按下两个 shift 键,它就会使屏幕空白。

kb_int      proc    far
            pushf                           ;Save FLAGS
            push    ax                      ;Save AX
            in      al,60h                  ;Read the scan code
            mov     cs:[scancode],al        ;Save it
            pop     ax                      ;Restore AX
            popf                            ;Restore FLAGS
            pushf                           ;Push FLAGS
            call    cs:[int09h]             ;Call previous handler
            sti                             ;Enable interrupts

            test    cs:[scancode],80h       ;Exit if high bit of scan
            jnz     kb_exit                 ;  code is set

            push    ax                      ;Save AX and ES
            push    es
            mov     ax,40h                  ;Point ES to the BIOS
            mov     es,ax                   ;  Data Area
            mov     al,es:[17h]             ;Get keyboard flags
            and     al,03h                  ;Zero the upper 6 bits
            cmp     al,03h                  ;Are the Shift keys pressed?
            pop     es                      ;Restore AX and ES
            pop     ax
            jne     kb2                     ;Branch if they're not
            call    disable_video           ;Blank the screen
            iret                            ;Return from interrupt
kb2:        push    cs:[time]               ;Reset countdown timer
            pop     cs:[count]
            cmp     cs:[blanked],0          ;Is the screen blanked?
            je      kb_exit                 ;If not, then exit
            call    enable_video            ;Unblank the screen
kb_exit:    iret                            ;Return from interrupt
kb_int      endp

这是挂钩中断的代码 - 这在程序的开头运行

            mov     ax,3509h                ;Hook interrupt 09H
            int     21h
            mov     word ptr int09h,bx
            mov     word ptr int09h[2],es
            mov     ax,2509h
            mov     dx,offset kb_int
            int     21h

整个程序太长,无法在此处发布 - 33KB。但是,您只想看一个如何做的例子......

这是另一个检查各种 alt/ctrl/key 功能的示例

even
New_09     proc   far
           sti
           pushf
           push   ax
           mov    ah, 2                 ; get shift key status
           int    16h
           and    al, 0Fh
           cmp    al, 12                ; alt/ctrl?
           jne    @@0                   ; no
           in     al, 60h
           cmp    al, 19                ; 'R'?
           je     @@1                   ; yes
           cmp    al, 31                ; 'S'
           je     @@1                   ; yes
           cmp    al, 16                ; 'Q'
           je     @@1                   ; yes
@@0:       pop    ax                    ; exit if not my hotkey
           popf
           jmp    cs:old_09

@@1:       push   bp
           mov    bp, ax                ; save scan code
           in     al, 61h               ; reset keyboard
           mov    ah, al
           or     al, 80h
           out    61h, al
           mov    al, ah
           out    61h, al
           cli
           mov    al, 20h
           out    20h, al
           sti

           mov    ax, bp                ; restore scan code
           cmp    al, 16                ; was it Q?
           jne    @@GetMode

我现在不记得为什么需要所有的来龙去脉(这段代码来自 1992 年 5 月 14 日 - 二十年前!!!)。

于 2012-10-14T15:07:54.923 回答