安装一个新的int9 中断例程,功能:在DOS下,按下A键后,除非不松开,如果松开,就显示满屏幕的"A"
(1)自行编写的int9中断例程:
assume cs:code
stack segment //自定义栈段,其实也可以不需要
db 128 dup (0)
stack ends
code segment
start:
mov ax , stack
mov ss , ax
mov sp , 128
push cs //将当前的cs值转移到ds中
pop ds
mov ax , 0 //将自定义的9号中断处理程序(处理键盘事件)复制到内存0:204单元处
mov es , ax
mov si , offset int9
mov di , 204h
mov cx , offset int9end - offset int9
cld
rep movsb
push es:[9*4] //将系统自带的9号中断处理程序的地址保存到内存 0:200-0:203,因为我们还要调用系统的这个程序
pop es:[200h]
push es:[9*4+2]
pop es:[202h]
cli
mov word ptr es:[9*4] , 204h //将中断向量表的9号中断的地址设置为我们的程序的地址,顶替原来的地址
mov word ptr es:[9*4+2] , 0
sti
mov ax , 4c00h
int 21h
int9: //我们的键盘处理程序
push ax
push bx
push cx
push es
in al , 60h //读取键盘事件产生的码值
pushf
call dword ptr cs:[200h] //调用系统的键盘处理程序进行处理
cmp al , 9eh //判断这个事件是不是松开键'A',如果是,就执行我们的程序段(实现全屏'A'),否则本次键盘事件处理结束
jne int9ret
mov ax , 0b800h //一下实现全屏'A'
mov es ,ax
mov bx , 0
mov cx , 2000
s:
mov byte ptr es:[bx] , 'A'
add bx , 2
loop s
int9ret:
pop es
pop cx
pop bx
pop ax
iret
int9end :nop
code ends
end start
(2)测试程序:
assume cs:code
stack segment
db 128 dup (0)
stack ends
data segment
dw 0 , 0
data ends
code segment
start:
mov ax , stack
mov ss , ax
mov sp , 128
mov al , 100 //这个程序就将al从100减少到0,每次减1之前都延迟一段时间,延迟通过调用delay函数实现
s:
call delay
dec al
cmp al , 0
jne s
mov ax , 4c00h
int 21h
delay:
push ax
push dx
mov dx , 1000h
mov ax , 0
s1:
sub ax , 1
sbb dx , 0
cmp ax , 0
jne s1
cmp dx , 0
jne s1
pop dx
pop ax
ret
code ends
end start
先安装我们的中断处理程序,再运行测试程序,当按下A键,然后松开时候,即出现下面的结果: