int 9中断例程优化分析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/zhaixh_89/article/details/102640272

上篇文中我们已经实现了int9中断例程的编写,根据课后检测点我们对上文代码做出优化。代码如下:

assume cs:code

stack segment
	db 128 dup (0)
stack ends

data segment
	dw 0, 0
data ends

code segment
	    start:mov ax, stack
		  mov ss, ax
		  mov sp, 128
		  
		  mov ax, data
		  mov ds, ax
		  
		  ;保存原有int 9号中断处理程序的入口地址
		  mov ax, 0
		  mov es, ax
		  push es:[9*4]
		  pop ds:[0]
		  push es:[9*4+2]
		  pop ds:[2]
		  
		  mov word ptr es:[9*4], offset int9
		  mov es:[9*4+2], cs
		  
		  mov ax, 0b800h
		  mov es, ax
		  mov ah, 'a'
	      s1: mov es:[160*12+40*2], ah
		  call delay
		  inc ah
		  cmp ah, 'z'
		  jna s1
		  
		  ;为了不影响后续的键盘输入处理,需要将int 9号中断处理程序的入口地址恢复为原来的地址
		  push ds:[0]
		  pop es:[9*4]
		  push ds:[2]
		  pop es:[9*4+2]
		  mov ax, 4c00h
		  int 21h
		  
		  
	    delay:push ax
		  push dx
		  
		  mov ax, 0
		  mov dx, 1000h	;//cpu循环执行10000 000h次
	       s2:sub ax, 1
		  sbb dx, 0
		  cmp ax, 0
		  jne s2
		  cmp dx, 0
		  jne s2
		  pop dx
		  pop ax
		  ret
		  
	;-----------新的int 9中断例程-------------	  
	    int9: push ax
		  push bx
		  push es
		  
		  in al, 60h	;从端口60h读出键盘的输入
		  pushf	;标志寄存器入栈
		  
		  ;设置IF = 0, TF = 0
		  pushf
		  pop bx
		  and bh, 11111100B
		  push bx
		  popf
		  ;CS, IP入栈,IP = n*4, CS = n*4+2
		  call dword ptr ds:[0]	;对int指令进行模拟,调用原来的int 9中断例程
		  
		  cmp al, 1	;esc键的扫描码为1
		  jne int9ret
		  
		  mov ax, 0b800h
		  mov es, ax
		  inc byte ptr es:[160*12+40*2 + 1]	;属性值加1改变颜色
		  
		  
          int9ret:pop es
		  pop bx
		  pop ax
		  iret
code ends
end start 

仔细分析上面代码,可以发现,程序在进入编写的中断例程之前IF和TF都已经置0,对于程序段

pushf	;标志寄存器入栈

;设置IF = 0, TF = 0
pushf
pop bx
and bh, 11111100B
push bx
popf
;CS, IP入栈,IP = n*4, CS = n*4+2
call dword ptr ds:[0]	;对int指令进行模拟,调用原来的int 9中断例程

可以精简为:

pushf	;标志寄存器入栈
;CS, IP入栈,IP = n*4, CS = n*4+2
call dword ptr ds:[0]	;对int指令进行模拟,调用原来的int 9中断例程

另外,在主程序执行过程中,如果在执行设置int9中断例程的段地址和偏移地址的指令之间发生了键盘中断,则cpu将转去一个错误的地址执行,将发生错误,因此针对这一时间段,我们可以使用sti个cli指令来显示中断事件的处理。修改的代码如下:

cli    ;禁止中断发生
mov word ptr es:[9*4], offset int9
mov es:[9*4+2], cs
sti    ;允许中断发生

;为了不影响后续的键盘输入处理,需要将int 9号中断处理程序的入口地址恢复为原来的地址
cli
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
sti

猜你喜欢

转载自blog.csdn.net/zhaixh_89/article/details/102640272
int