intNum =9 ;中断向量号
exitKey ='x' ;循环的结束条件,按键X
;******************************************************************************
code segment
assume cs:code,ds:code
old9IEntryAddr dd 0 ;用于保存老的中断向量
;******************************************************************************
;新的中断服务程序,为了阅读方便的原因,写成了子函数的形式
new9IProc proc far
pushf ;以函数的形式调用中断,必须平衡栈
call cs:old9IEntryAddr ;调用老的中断服务程序
sti ;开中断
push ax
;调用16h的1号功能判断键盘缓冲区是否有数据,P177
mov ah,1
int 16h
mov ah,2
mov dl,'i'
int 21h
jz next
;若键盘缓冲区有数据则调用16h的0号功能读入键盘缓冲区的数据
mov ah,0
int 16h
;若键盘缓冲区有数据则判断读入的数据是是‘x’,则填写为055
cmp al,'x'
jne next
;读写CMOS RAM的20h单元,第一步送地址,第二步才能完成读写,P158
mov al,0ah
out 70h,al
jmp $+2
mov al,'x'
out 71h,al
jmp iEnd
;填写成0aah
next:
mov al,0ah
out 70h,al
jmp $+2
mov al,0aah
out 71h,al
iEnd:
pop ax
iret
new9IProc endp
;******************************************************************************
main proc far
start:
;设置数据段代码段为同一个段
push cs
pop ds
;读原始的中断向量
mov ah,35h
mov al,intNum
int 21h
mov word ptr cs:old9IEntryAddr,bx
mov word ptr cs:old9IEntryAddr+2,es
;设置新的中断向量
push ds
mov ax,seg new9IProc
mov ds,ax
mov dx,offset new9IProc
mov al,intNum
mov ah,25h
int 21h
pop ds
;先清除掉原来的值,避免再次运行程序原来的值的影响
mov al,20h
out 70h,al
jmp $+2
mov al,0aah
out 71h,al
;循环开始从端口读数据,直到读入55h
readAgain:
mov ah,02h
mov dl,'c'
int 21h
mov al,0ah
out 70h,al
jmp $+2
in al,71h
cmp al,'x'
jnz readAgain ;不为055h则继续读
;当读取到55h时,以十六进制形式显示读取数据的最低4位
mov dl,al
and dl,0fh
add dl,30h
cmp dl,39h
jbe output
add dl,7
output:
mov ah,2
int 21h
;恢复原始的中断向量
mov ax,word ptr cs:old9IEntryAddr+2
mov ds,ax
mov dx,word ptr cs:old9IEntryAddr
mov al,9
mov ah,25h
int 21h
mov ax,4c00h
int 21h
code ends
end start
汇编改写9号中断程序,下面讲解下改写程序流程,程序顺序执行到改写9号中断那里 改写完成后 键盘中断就变成了新的9号中断,在其后又一个循环一直循环查询CMOS单元的0ah端口,此时在屏幕上显示的是一个下划线一直跳转也就是一直等待。当你按下键盘时,调用9号键盘中断会向CMOS0ah单元写入数据,写入数据后,主程序循环检测到x所以跳出循环。