首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 汇编语言 >

求教,轮换了自己的键盘中断服务程序之后,不知为何恢复不了

2013-06-25 
求教,替换了自己的键盘中断服务程序之后,不知为何恢复不了。我在写一个关于中断控制芯片 8259A 的汇编程序。

求教,替换了自己的键盘中断服务程序之后,不知为何恢复不了。
我在写一个关于中断控制芯片 8259A 的汇编程序。其中我替换了系统的键盘中断服务程序(中断向量号是 09h),执行完任务之后恢复系统中断始终不行。所以返回 DOS 后键盘无法输入(是 OS X 下的 DOSBox)。我自己对照课本的类似代码研究一天了,没看出问题,请各位赐教。

以下是我的部分代码:


.model small
.stack
.data
intmsg0db 'IR0 = 0 in ISR',0dh,0ah,0
intmsg1db 'IR0 = 1 in ISR',0dh,0ah,0
counterdb 0
isrdb 0
myseg8dw 0
myoffset8dw 0
myseg9dw 0
myoffset9dw 0
.code
start:
mov ax,@data
mov ds,ax
mov ax,3508h; 获取原 08h 中断服务程序入口
int 21h
mov myseg8, es; 保存原 08h 中断服务程序入口
mov myoffset8, bx

mov ax,3509h; 获取原 09h 中断服务程序入口
int 21h
mov myseg9, es; 保存原 09h 中断服务程序入口
mov myoffset9, bx

cli
push ds
mov ax,seg new08h; 重设 08h 中断(定时器)
mov ds,ax
mov dx,offset new08h
mov ax,2508h
int 21h

mov ax,seg new09h; 重设 09h 中断(键盘)
mov ds,ax
mov dx,offset new09h
mov ax,2509h
int 21h
pop ds
; 设置允许 IR0、IR1 中断
in al,21h
push ax
and al,0fch; 允许 IRQ0 与 IRQ1,IRQ0 比 IRQ1 的优先级高
out 21h,al
mov counter,0
sti

start1:
cmp counter,10    ; 循环十次处理 08h 中断
jb start1

cli
pop ax
out 21h,al

mov ax, myseg9    ; 恢复 09h 中断服务程序
mov ds, ax
mov dx, myoffset9
mov ax, 2509h
int 21h

mov ax, myseg8    ; 恢复 08h 中断服务程序
mov ds, ax
mov dx, myoffset8
mov ax, 2508h
int 21h

sti
mov ax,4c00h
int 21h

new08hproc
cli
push ax
push bx
push ds
mov al,68h; 向 ocw3 写入,设置特殊屏蔽模式
out 20h,al

in al,21h
or al,01h; 屏蔽 IR0
out 21h,al; 向 ocw1 写入

mov al,00001011b; 向 ocw3 写入,下一读指令,读 ISR
out 20h,al
in al,20h
mov isr,al; 保存从 ISR 读出的值
sti
mov ax,@data
mov ds,ax
test isr,01h
inc counter
jnz isr1
mov si,offset intmsg0
call dpstri
jmp end08h
isr1:
mov si,offset intmsg1
call dpstri
end08h:
cli
in al,21h
and al,0feh; 允许 IR0
out 21h,al; 向 ocw1 写入
sti
mov al,20h; 发送 EOI
out 20h,al
pop ds
pop bx
pop ax
iret
new08hendp
new09h proc

iret
new09h endp
dpstriproc
push ax
push bx
dps1:
lodsb
cmp al,0
jz dps2
mov bx,0
mov ah,0eh
int 10h
jmp dps1
dps2:
pop bx
pop ax
ret
dpstriendp
end start
汇编 键盘 中断


[解决办法]
首先你最后的恢复中断向量时的做法是错误的

mov ax, myseg9    ; 恢复 09h 中断服务程序
mov ds, ax
mov dx, myoffset9  ; 上面设置 ds 指向了原 int9 的段,不再是自己的数据段了,
           ;  所以这里获得的 dx 就是错误的。下面的 int8 的恢复也一样
mov ax, 2509h
int 21h

另外,即使这里的代码都改正了获得了原来的向量并进行了恢复,键盘好像还是无响应了,是不是你的代码里对中断端口控制操作上没有恢复?

热点排行