我们在之前编写的int9安装例程基础上加一个功能
功能:在DOS下,按F1键后改变屏幕当前的显示颜色,其他的按键照常处理。
我们简单分析一下:
(1)改变屏幕的显示颜色
我们知道,在80x25的彩色字符模式显示缓冲区中每页约有4000个字节的内容显示在屏幕上,因此程序如下:
mov ax, 0b800h
mov es, ax
mov bx, 1
mov cx, 2000
s: inc byte ptr es:[bx] ;属性值加1改变颜色
add bx, 2
loop s
(2)其他按键照常处理
可以调用原有的int9中断处理程序
(3)原有int9中断例程的保存
因为我们在编写的int9中断例程中要调用原来的int9中断例程,因此要保存原有int9中断例程,显然不能保存在安装程序中,因为安装程序返回后地址
将丢失,因此我们将地址保存在0:200单元处
(4)新int9中断例程
我们将新int9中断例程安装在0:204单元处
完整的程序如下:
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
pop ds ;这里赋值只是用来复制代码块
mov si, offset int9
mov ax, 0
mov es, ax
mov di, 204h
mov cx, offset int9end - offset int9
cld
rep movsb
;保存原有int 9号中断处理程序的入口地址
push es:[9*4]
pop es:[200h]
push es:[9*4+2]
pop es:[202h]
cli
mov word ptr es:[9*4], 204h
mov word ptr es:[9*4+2], 0
sti
mov ax, 4c00h
int 21h
;-----------新的int 9中断例程-------------
int9: push ax
push bx
push cx
push es
in al, 60h ;从端口60h读出键盘的输入
pushf ;标志寄存器入栈
;CS, IP入栈,IP = n*4, CS = n*4+2
call dword ptr cs:[200h] ;对int指令进行模拟,调用原来的int 9中断例程
cmp al, 3bh ;F1键的扫描码为3bh
jne int9ret
mov ax, 0b800h
mov es, ax
mov bx, 1
mov cx, 2000
s: inc byte ptr es:[bx] ;属性值加1改变颜色
add bx, 2
loop s
int9ret:pop es
pop cx
pop bx
pop ax
iret
int9end:nop
code ends
end start
程序执行结果:
总结:
(1)外设的输入送入端口
(2)向cpu发出外中断(可屏蔽中断)信息
(3)cpu检测到可屏蔽中断信息,如果IF=1,cpu在执行完当前指令后响应中断,执行相应的中断例程
(4)可在中断例程中实现实现对外设输入的处理。
端口和中断机制,是cpu进行I/O的基础。