[Chapter 15] - [实验15]

思考

  • 需要1个安装程序
    • 安装新int9
    • 老int9入口备份
    • 新int9入口注册
  • 需要重写1个新int9,并在其中模拟调用老int9以处理硬件信息
    • 按键A的处理
      • 如果松开A,就显示满屏幕A:端口60h接收到的是断码9Eh (计算方法,通用1Eh+80h=8Eh)
      • 还要考虑到是大写的A,因为只对al接收到的信息与8Eh比较,将对小a的输入也会做出同A一样的响应,而题目要求只对大写A响应。CapsLock键属于控制键,它的状态位于0040:17单元中的第6位,也需要单独判断
      • 如果没有松开,则按普通键盘处理
    • 非按键A的处理

代码

;任务:安装新的int9中断例程
;功能:在DOS下,按下‘A’后,除非不再松开,如果松开,就显示满屏的‘A’,其他的键照常处理

;安装程序
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;或 code
		pop ds

		mov ax,0
		mov es,ax

		;将 新int9 安装到目标位置
		mov si,offset int9
		mov di,204h
		mov cx,offset int9end - offset int9
		cld
		rep movsb

		;备份 老int9 入口
		push es:[4*9]
		pop es:[200h]
		push es:[4*9+2]
		pop es:[202h]

		;在中断向量表中注册 新int9 入口
		cli;更改过程不能被打断
		mov ax,204h
		mov es:[4*9],ax
		push es
		pop es:[4*9+2]
		sti

		mov ax,4c00h
		int 21h

;----搭载 新int9----
int9:	push ax
		push bx
		push cx
		push es

		in al,60h

		;只调用1次,因为不论任何键盘字符输入,都需要调用
		pushf
		call dword ptr cs:[200h];因int9中的结尾iret包含着popf,所以需要在开头模拟pushf

			;判断是否键盘的是A或a,二者扫描码都是1Eh
			cmp al,1Eh+80h;A扫描码为1Eh,断码为1Eh+80h=9Eh
			jne int9ret

			;判断CapsLock是否按下,避免对小写a也做出同样响应
			mov bx,40h;用bx是因为al承担着从端口60h接收信息的任务,不能被覆盖
			mov es,bx
			mov bl,es:[17h]
			and bl,01000000b;将第6位之外的所有位,清零。本语句不对第6位造成修改,0表示小写,1表示大写
			cmp bl,0
			je int9ret

			looseA:	;对按键A响应,将A写满屏
					mov bx,0b800h
					mov es,bx
					mov bx,0
					mov cx,2000
			s:		mov byte ptr es:[bx],'A'
					add bx,2
					loop s

int9ret:pop es
		pop	cx
		pop	bx
		pop ax
		iret

int9end:nop

code ends
end start
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值