我正在尝试在按下某个键时覆盖默认中断。 这是我的代码:我不明白为什么它不起作用,它适用于其他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
答案 0 :(得分:1)
我从我的档案中挖出了以下代码(日期为24/06/1995);这是我编写的程序的键盘处理程序,如果按下两个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
我现在不记得为什么需要所有的细节(这段代码是从14/05/1992 - 二十年前!!!!)。
答案 1 :(得分:1)
我会再次尝试回答这个问题 - 以一种冗长的方式。
在Windows普及之前,DOS统治了计算机。为了扩展其功能,人们习惯于编写TSR(终止和驻留)程序;这些程序将挂钩各种中断函数(如时钟和键盘),终止然后驻留在内存中。因此,当发生给定中断时,这些实用程序的常驻代码将处理中断,可能调用原始中断处理程序。
此类程序的结构由两部分组成:瞬态部分和常驻部分。瞬态部分将是从命令行调用程序时运行的代码;这将检查是否已经安装了常驻部件。如果驻留部件已经安装,程序将只是退出,但如果这是第一次调用,程序将首先保存当前中断处理程序的地址,然后安装自己的代码作为新的中断处理程序,然后进行特殊的DOS调用,将处理程序代码留在内存中。
您显示的代码是瞬态程序的一部分,其中新的中断处理程序安装在中断表中。这段代码应该只运行一次,当然不是新中断处理程序本身的一部分。
当Windows的使用普及时,TSR程序已经过时了。从某种意义上说,在Windows下运行的每个程序都是一个TSR程序,键盘中断处理程序代码现在变成了一个键盘事件,在“OnKeyPress”函数中处理(例如在Delphi中)。
以下代码更改了中断表
mov ax, 2509h
mov dx, offset kb_handler
int 21h
从地址* kb_handler *开始的代码是实际的中断处理程序。
您正在做的是重复设置中断处理程序的地址而不是处理中断。上面的代码应该只在程序本身安装时运行一次;中断处理程序代码将被多次调用。
我希望这会让事情更加清晰。
你没有写的是你为什么要这样做。