【发布时间】:2017-08-07 00:28:12
【问题描述】:
如何在 DOS 中正确设置并重置键盘 ISR? (x86 汇编,实模式,16 位,带 TASM)
我有以下为键盘设置 ISR 的汇编代码。它应该做的就是每次按下一个键时打印一个句子,最多五次。然后它应该退出。
ISR 似乎安装正确。每次按下一个键(一次向下,一次向上)时,它会打印出一个句子。但是,似乎我错误地卸载了 ISR,因为在运行程序后我无法在 DOS 命令行中输入文本。
(由于目前收到的反馈,我已更新以下代码以在 ISR 中存储/恢复 DS、从端口 60h 读取并处理 EOI 调用。)
.model small
.data
our_text db "Interrupt intercepted", 0dh, 0ah, "$"
old_int_seg dw 0
old_int_off dw 0
keyCount dw 0
.code
.startup
cli
mov ah, 035 ; get current keyboard int vector
mov al, 09h ; and save it, so we can restore it later
int 21h
mov [old_int_off], bx
mov bx, es
mov [old_int_seg], bx
mov ax, cs
mov ds, ax ; load data segment with code segment
;(the one we are in now)
mov ah, 25h ; Set Interrupt Vector Command
mov al, 9 ; Interrupt to replace
lea dx, ISR ;load dx with our interrupt address
int 21h
sti
mov ax,@data
mov ds,ax
infinite:
mov ax,keyCount[0]
cmp ax,5
jl infinite ;check for 5 presses
cli ;restore old interrupt
mov ax, [old_int_seg]
mov ds, ax
mov dx, [old_int_off]
mov ah, 25h
mov al, 09h
int 21h
sti
mov ah,4Ch ; quit
mov al,00h
int 21h
ISR proc far
; save old registers
push ax
push cx
push dx
push bx
push sp
push bp
push si
push di
push ds
mov ax,@data ;print text
mov ds,ax
xor ah,ah
mov ah, 9
lea dx, our_text
int 21h
mov ax,keyCount
inc ax
mov [keyCount],ax
in al, 60h
; send EOI to keyboard
in al, 61h
mov ah, al
or al, 80h
out 61h, al
mov al, ah
out 61h, al
; send EOI to master PIC
mov al, 20h
out 20h, al
pop ds
pop di
pop si
pop bp
pop sp
pop bx
pop dx
pop cx
pop ax
iret
ISR endp
我在恢复原始键盘 ISR 的方式上有什么问题?为什么我在运行程序后无法在 DOS 的命令提示符中输入任何内容?
【问题讨论】:
-
您的键盘 ISR 必须从端口 0x60 读取一个字节,否则您将不会发生后续中断。您还必须向 PIC(可编程中断控制器)发送中断结束
-
由于您更改了 DS,您的中断处理程序还应该保存和恢复 DS 的值,就像您可能修改的所有其他寄存器一样。跨度>
-
@MichaelPetch,感谢您的出色建议。我现在从 0x60 读取字节,向键盘和 PIC 发送 EOI 信号,并保存/恢复 DS。 (我已经更新了我的问题中的所有代码以反映这些更改。)该程序现在可以正常运行,除了一件小事:程序终止后我无法在 DOS 命令行中输入任何文本,所以我想我是没有正确恢复原始 ISR?
-
mov ah, 035应该是mov ah, 35h。您调用了错误的软件中断并为向量获取了垃圾。另一个问题是此代码不正确:mov ax, [old_int_seg]mov ds, axmov dx, [old_int_off]在读取不正确的偏移量之前更改 DS。应该是mov ax, [old_int_seg]mov dx, [old_int_off]mov ds, ax -
你太棒了!非常感谢你。既然您在 cmets 中给出了答案,那么我有什么方法可以为您提供答案吗?
标签: assembly keyboard interrupt-handling tasm x86-16