8086汇编(10、int9键盘中断)

本文介绍了一个通过键盘中断INT 9处理程序,实现按F1键不断改变屏幕颜色的示例。代码首先保存原中断处理程序,然后设置新的中断处理程序。在新中断处理程序中,当检测到F1键按下时,调用函数改变屏幕颜色。通过这种方式,实现了在保持硬件事件正常处理的同时,增加了自定义功能。文章还详细解释了中断处理过程中的栈平衡原理。
摘要由CSDN通过智能技术生成

今天我们来实现个功能按F1 不断改变屏幕颜色
概念:
按键盘会产生扫描码

  • 通码 按住不放
  • 断码 弹起,通码+80H
    int9中断对应的端口为60H,也就是我们按下键盘,就可以从60H中读取到扫描码

扫描码的对照表可以参考这篇文章:
键盘按键的各种编码对照表

如果我们直接改变int9,那么硬件层面的一些其它操作细节会就无法继续了,比如控制键的状态信息的填充,比如后续硬件的应答事件。所以这里我们需要做个事情就是在调用int9之前做一个拦截。也就是我们先从60H端口中把数据读走,然后在调用它原来的中断,做后续硬件事件发出应答。
代码如下:

DATAS SEGMENT
    ;此处输入数据段代码  
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
    call cpy_new_int9	;设置新的in9代码到安全区
    call save_old_int9	;保存旧的移动旧的int9向量到0:200位置
    call set_new_int9  	;设置新得int9到对应位置。
    MOV AH,4CH
    INT 21H

;============================================    
set_new_int9:
	mov bx,0
	mov es,bx
	cli
	mov word ptr es:[9*4],7E00H      	;低2个字节给ip
	mov word ptr es:[9*4+2],0           ;高2个字节给cs
	sti
	ret    
;============================================    
save_old_int9:
	mov bx,0
	mov es,bx
	cli
	push es:[9*4]         ;ip
	push es:[9*4+2]		;cs
	pop es:[202H]		;cs
	pop es:[200H]		;ip
	sti
	ret    
;============================================
new_int9:
	push ax
	in al,60H                           ;从端口读取数据
	pushf									;保存标志位
	call dword ptr cs:[200H]		;调用原中断
	
	cmp al,3BH						;读到得内容与F1比较
	jne int9Ret						;不相等则直接退出,相等执行改变屏幕颜色
	call change_screen_color
	
int9Ret:
	pop ax
	iret 	
;============================================        
change_screen_color:
	push bx
	push es
	push cx

	mov bx,0B800H
	mov es,bx
	mov bx,1									;奇数位保存颜色属性信息
	mov cx,2000							;整个屏幕2000个字符
changeColor:
	inc byte ptr es:[bx]
	add bx,2
	loop changeColor
	pop cx
	pop es
	pop bx
	ret
    		
new_int9_end: nop    
;============================================
cpy_new_int9:
	mov bx,0
	mov es,bx
	mov di,7E00H
	
	mov bx,cs
	mov ds,bx
	mov si,OFFSET new_int9
	
	mov cx,OFFSET new_int9_end-OFFSET new_int9

	cld
	rep movsb
	ret
;============================================    
CODES ENDS
    END START

先来看下效果:
多按几下F1 可以看到颜色不断在变化。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

这里着重介绍下这两行代码,怎么达到栈平衡

pushf				
call dword ptr cs:[200H]

当我们调用我们自己得中断得时候
实际执行了
pushf
push cs
push ip

然后我们又执行了
pushf
接着调用call得时候
实际执行了
push cs
push ip
所以现在栈里面是
pushf
push cs
push ip
pushf
push cs
push ip
而调用完原中断之后就执行了
pop ip
pop cs
popf
最后执行我们自己得iret得时候又把栈内容pop出来了所以达到栈平衡了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值