安装一个新的int 9中断例程,功能:在DOS下,按下“A”键后,除非不再松开,如果松开,就显示满屏幕的“A”;其他的键照常处理。
分析:由书中介绍可知,按健A的通码为1EH,因为断码=通码+80H,故释放按键A时产生的描述码为1EH+80H;
由题,要保证其他键照常处理,则说明在按其他键时,必须用原先的int 9中断处理程序;因为新编写的int 9中断程中要调用原int 9中断例程,所以,要保存原int 9中断例程的入口地址,故设置将原int 9中断例程的入口地址保存在0:200单元处。接着将新的中断程序安装在0:204处。
参考代码:
assume cs:codesg
codesg segment
start: mov ax,cs
mov ds,ax ; 设置ds=cs
mov ax,0
mov es,ax ; 设置es=0
mov si,offset int9
mov di,204H ; 因为0:200字单元存IP,0:202字单元存CS,故程序从0:204开始
mov cx,offset int9end - offset int9
cld
rep movsb ; 复制新的中断程序于内存单元的0:204处
mov ax,es:[4*9]
mov es:[200H],ax
mov ax,es:[4*9+2]
mov es:[202H],ax ; 保存原先的int 9 中断处理程序地址于0:200处
cli
; 设响CPU不响应可屏蔽中断,防止下面更新9号中断向量项时,指向错误地址
mov word ptr es:[4*9],204H
mov word ptr es:[4*9+2],0
sti ; 设置CPU响应可屏蔽中断,即使得用户按键则执行9号中断程序
mov ax,4c00h
int 21h
int9: push ax
push es
push di
push cx
in al,60H ; 读取用户输入的键盘扫描码
pushf
call dword ptr cs:[200h] ; 调用原来的BIOS中的9号中断例程,当前cs=0
cmp al,1EH+80H ; 判断是否为释放按键A
jne int9ret
mov ax,0B800H
mov es,ax
mov di,0
mov cx,80*25
s: mov byte ptr es:[di],'A' ; 显示"A"
inc byte ptr es:[di+1] ; 更改颜色
add di,2
loop s
int9ret: pop cx
pop di
pop es
pop ax
iret
int9end: nop
codesg ends
end start
在MS-DOS 7.10中运行如下:
注意:这里添加了一行更改颜色代码,故当你按下A时,全屏中显示A,并变化颜色。