任务:安装一个新的 int 9 中断例程,功能:在 DOS 下,按 F1 键后改变当前屏幕的显示颜色,其他的键照常处理。
		
		| 1、改变屏幕的显示颜色; 改变从 B8000 开始的 4000 个字节中的所有奇地址单元中的内容,当前屏幕的显示颜色即发生改变。            mov ax , 0b800h
							 
							        mov es , ax
							 
							        mov bx , 1
							 
							        mov cx , 2000
							 
							s:        inc byte ptr es:[bx]
							 
							        add bx , 2
							 
							        loop s
							 
						 | 
					
| 2、其他键照常处理; 可以调用原 int 9 中断处理程序,来处理其他的键盘输入。  | 
					
| 3、原 int 9 中断例程的入口地址保存; 因为在编写的新 int 9 中断例程中要调用原 int 9 中断例程处理键盘输入的其他细节,所以,要保存原 int 9 中断例程的入口地址。因为安装程序返回后地址将丢失,所以可以选择将地址保存在 0:200 单元处。这个地方是开辟给中断向量表的,其他程序不能访问,但是向量表用不了这么多。  | 
					
| 4、新 int 9 中断例程的安装 可以从 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 ax , 0
							 
							        mov es , ax
							 
							        mov si , offset int9        ; 安装新中断例程地址
							 
							        mov di , 204h
							 
							        mov cx , offset int9end- offset int9
							 
							        cld
							 
							        rep movsb
							 
							        push es:[9*4]        ; 保存原int 9中断例程入口地址
							 
							        pop es:[200h]
							 
							        push es:[9*4+2]
							 
							        pop es:[202h]
							 
							        cli        ; 关可屏蔽中断
							 
							        mov word ptr es:[9*4] , 204h        ; 设置新的int 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]        ; 当9号中断执行的时候(CS)=0
							 
							;这里调用原int 9中断例程,我们事先把原9号中断例程的入口地址存放在0:[200]~0:[204]
							 
							;之所以要调用原9号中断例程,是因为还要处理其它细节
								 
								;eg:扫描码加上ASCII放到键盘输入缓冲区,状态字节放到0040:17
								 
							        cmp al , 3bh        ;  F1 键的扫描码是 3bh
							 
							        jne int9ret
							 
							        mov ax , 0b800h
							 
							        mov es , ax
							 
							        mov bx , 1
							 
							        mov cx , 2000        ; 25*80=2000 一页可以存2000个字符,每个字符要存一个字符属性,25*160=4000
							 
							s:      inc byte ptr es:[bx]        ; 循环修改显示页面能存储的所有字符的显示属性
							 
							        add bx , 2
							 
							        loop s
							 
							int9ret:        pop es
							 
							        pop cx
							 
							        pop bx
							 
							        pop ax
							 
							        iret
							 
							int9end:        nop
							 
							code ends
							 
							end start
							 
						 | 
					
| 
							 assume cs:code
							 
							stack segment
							 
							        db 128 dup (0)
							 
							stack ends
							 
							code segment
							 
							start:        mov ax , stack
							 
							        mov ss , ax
							 
							        mov sp , 128
							 
							        mov ax , 4c00h
							 
							        int 21h
							 
							code ends
							 
							end start
							 
						 | 
						
                    
                
                
            
        
浙公网安备 33010602011771号