第十五章 外中断

检测点15.1

(1)仔细分析一下上面的int 9中断例程,看看是否可以精简一下?

其实在我们的int 9中断例程中,模拟int指令调用原int 9中断例程的程序段是可以精简的,因为在进入中断例程后,IF和TF都已经置零,没有必要再进行设置了。对于程序段:

pushf                           ;标志寄存器值入栈
pushf                           ;标志寄存器值入栈
pop ax                          ;标志寄存器值弹栈到ax中
and ah, 11111100B               ;标志寄存器值第八位与第九位(IF、TF) 按位与
push ax                         ;将修改后的ax第值入栈
popf                            ;将修改后的值弹栈到标志寄存器中,此时第IF & TF位值为0
call word ptr ds:[0]            ;调用原int9中断例程

可以精简为:

  1. pushf
  2. call word ptr ds:[0]

即免去了IF与TF位赋值位0第操作。(第一条第pushf是为了配合中断例程返回时的iret指令的popf操作)

(2)仔细分析上面程序中的主程序,看看有什么潜在的问题?

在主程序中,如果在执行设置int 9中断例程的段地址和偏移地址的指令之间,发生了键盘中断,则CPU将转去一个错误的地址执行,将发生错误。找出这样的程序段,改写它们,排除潜在的问题。
提示:注意sti和cli指令的用法。

解:问题描述中已经给出了解法:通过sti与cli使设置int9中断例程的段地址和偏移地址的过程是不可被中断的。

1.中断向量表中注册新的int9中断例程时
cli
mov word ptr es:[9*4],offset int9
mov word ptr es:[9*4+2],cs
sti

2.复原int9中断例程在中断向量表中的源地址
cli
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
sti

实验15:安装新的int 9中断例程

assume cs:codesg

codesg segment
start:
	push cs 		;int 9中断例程的安装程序
	pop ds
	mov si,offset int9
	mov ax,0000H
	mov es,ax
	mov di,204H		;预留2个字的大小存储原int9例程的内存位置
	mov cx,offset int9end - offset int9
	cld
	rep movsb

	mov ax,0000H		;在预留的两个字的空间中[0:200, 0:203],保留原来的例程的入口地址
	mov es,ax
	push es:[9*4]   	;原例程的ip压栈
	pop es:[200H]   	;弹栈到0:200H
	push es:[9*4+2] 	;原例程的cs压栈
	pop es:[202H]   	;弹栈到0:202H处

	cli			;设置中断向量表,指向新的int9例程
	mov word ptr es:[9*4],204H
	mov word ptr es:[9*4+2],0000H
	sti

	mov ax,4c00H
	int 21H
;---
;子程序名称:int9
;功能:int9例程的扩展,当A键松开时,屏幕展示满字符A
;入口参数:无
;返回值:无
;---
int9:
	push ax 			;保存寄存器值
	push bx
	push cx
	push es

	in al,60H			;读取60H端口的扫描码
	pushf 				;标志寄存器值栈,需要配合原int9中断例程中的iret指令
	call dword ptr cs:[200H] 	;调用原int9中断例程(注:原int9中断例程的cs与ip在cs:[200H]处)

	cmp al,9EH		  	;A键的通码为1EH,断码为9EH。对比键入扫描码
	jne short int9ret 		;如果不是A键的断码,则结束
	
	mov ax,0b800H			;满屏显示A字符
	mov es,ax
	mov bx,0
	mov cx,2000     		;80列*25行共2000个字符
writeA: 
	mov byte ptr es:[bx],41H
	add bx,2
	loop writeA 

int9ret:
	pop es			 	;还原寄存器值
	pop cx
	pop bx
	pop ax
	iret
int9end: nop
codesg ends

end start
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值