我是靠谱客的博主 和谐煎蛋,最近开发中收集的这篇文章主要介绍王爽《汇编语言》第三版 编写INT9中断例程,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

欢迎扫码关注微信公众号
在这里插入图片描述

代码如下:

assume cs:code
data segment
	dw 0, 0
data ends
code segment  
start:	mov bx, 0
		mov es, bx
		mov ax, data
		mov ds, ax
		push es:[9*4]
		pop ds:[0]
		push es:[9*4+2]
		pop ds:[2]		;保存原来int9的地址
		
		mov word ptr es:[9*4], offset int9
		mov es:[9*4+2], cs
		
		mov ax, 0b800h
		mov es, ax
		mov ah, 'a'

s:		mov es:[12*160+40*2], ah
		call delay
		inc ah 
		cmp ah, 'z'
		jna s
		
		;在程序结束的时候恢复int9中断例程
		mov ax, 0
		mov es, ax
		push ds:[0]
		pop es:[9*4]
		push ds:[2]
		pop es:[9*4+2]
		mov ax, 4c00h
		int 21h 

delay:	push dx
		push ax
		mov dx, 10h
		mov ax, 0		;dx作高位,ax作低位,结合下面的循环,就会执行10000000h次
s1:		sub ax, 1
		sbb dx, 0
		cmp ax, 0
		jne s1
		cmp dx, 0
		jne s1
		pop ax
		pop dx
		ret
	
int9:	push ax
		push bx
		push es
		in al, 60h
		;模拟int9的调用
;-------------------------------------------;
		pushf
		pushf
		pop bx
		and bh, 11111100b
		push bx
		popf	
		call dword ptr ds:[0]
		cmp al, 1				;ESC的扫描码是01h,
								;因此,只需要看它的低位是不是1就知道接收到的是不是ESC键了
;-------------------------------------------;		
		jne int9ret
		
		mov ax, 0b800h
		mov es, ax
		inc byte ptr es:[12*160+40*2+1]
int9ret:pop es
		pop bx
		pop ax
		iret
code ends
end start
	
		

; int指令的调用
	; 1、标志寄存器入栈:	
		; pushf
	; 2、将TF、IF标志位置为0
		; TF和IF在标志寄存器的第8和第9位置(最低位是0)
		; pushf
		; pop ax
		; and ah, 11111100b
		; push ax
		; popf	;将处理后的标志寄存器的值通过栈传回标志寄存器
		; 3、CS、IP入栈
		; 4、IP=n*4, CS=n*4+2 
	; 3、上面的两部可以合为一个操作:
		; call dword ptr ds:[0]
		; 相当于:
			; push CS
			; push IP
			; IP=(ds)*16+0 
			; CS=(ds)*16+2

安装int9中断例程

assume cs:code 
code segment  
start: 	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]
		pop es:[200h]
		push es:[9*4+2]
		pop es:[202h]		;将系统的中断例程暂存在0:200和0:202单元中
		;在设置中断向量表时屏蔽中断
		cli
		mov word ptr es:[9*4], 204h
		mov word ptr es:[9*4+2], 0	;将新的中断例程起始地址填入中断向量表
		sti
		
		mov ax, 4c00h
		int 21h

; s:		mov es:[12*160+40*2], ah
		; call delay
		; inc ah 
		; cmp ah, 'z'
		; jna s
		
		; ;在程序结束的时候恢复int9中断例程
		; mov ax, 0
		; mov es, ax
		; cli
		; push ds:[0]
		; pop es:[9*4]
		; push ds:[2]
		; pop es:[9*4+2]
		; sti
		; mov ax, 4c00h 
		; int 21h 

; delay:	push dx
		; push ax
		; mov dx, 10h
		; mov ax, 0		;dx作高位,ax作低位,结合下面的循环,就会执行10000000h次
; s1:		sub ax, 1
		; sbb dx, 0
		; cmp ax, 0
		; jne s1
		; cmp dx, 0
		; jne s1
		; pop ax
		; pop dx
		; ret
	
int9:	push ax
		push bx
		push cx
		push es
		in al, 60h  
		 pushf
		; pushf
		; pop bx
		; and bh, 11111100b
		; push bx
		; popf	
		call dword ptr cs:[200h]	;这段代码执行时cs是0
		cmp al, 3bh	
		jne int9ret
		
		mov ax, 0b800h
		mov es, ax
		mov bx, 1
		mov cx, 2000
	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
	
		

; int指令的调用
	; 1、标志寄存器入栈:	
		; pushf
	; 2、将TF、IF标志位置为0
		; TF和IF在标志寄存器的第8和第9位置(最低位是0)
		; pushf
		; pop ax
		; and ah, 11111100b
		; push ax
		; popf	;将处理后的标志寄存器的值通过栈传回标志寄存器
		; 3、CS、IP入栈
		; 4、IP=n*4, CS=n*4+2 
	; 3、上面的两部可以合为一个操作:
		; call dword ptr ds:[0]
		; 相当于:
			; push CS
			; push IP
			; IP=(ds)*16+0 
			; CS=(ds)*16+2

实验15:

assume cs:code 
code segment  
start: 	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]
		pop es:[200h]
		push es:[9*4+2]
		pop es:[202h]		;将系统的中断例程暂存在0:200和0:202单元中
		;在设置中断向量表时屏蔽中断
		cli
		mov word ptr es:[9*4], 204h
		mov word ptr es:[9*4+2], 0	;将新的中断例程起始地址填入中断向量表
		sti
		
		mov ax, 4c00h
		int 21h

; s:		mov es:[12*160+40*2], ah
		; call delay
		; inc ah 
		; cmp ah, 'z'
		; jna s
		
		; ;在程序结束的时候恢复int9中断例程
		; mov ax, 0
		; mov es, ax
		; cli
		; push ds:[0]
		; pop es:[9*4]
		; push ds:[2]
		; pop es:[9*4+2]
		; sti
		; mov ax, 4c00h 
		; int 21h 

; delay:	push dx
		; push ax
		; mov dx, 10h
		; mov ax, 0		;dx作高位,ax作低位,结合下面的循环,就会执行10000000h次
; s1:		sub ax, 1
		; sbb dx, 0
		; cmp ax, 0
		; jne s1
		; cmp dx, 0
		; jne s1
		; pop ax
		; pop dx
		; ret
	
int9:	push ax
		push bx
		push cx
		push es
		in al, 60h  
		 pushf
		; pushf
		; pop bx
		; and bh, 11111100b
		; push bx
		; popf	
		call dword ptr cs:[200h]	;这段代码执行时cs是0
		cmp al, 9eh		;只要检测到A的断码,就持续输出A,指导屏幕满掉
		jne int9ret
		
		mov ax, 0b800h
		mov es, ax
		mov bx, 0
		mov cx, 2000	;一个屏幕80*25   4000byte,每次增2,只需循环2000次
		mov ah, 255
	s:	mov al, 'A'
		mov byte ptr es:[bx], al 
		mov byte ptr es:[bx+1], ah
		dec ah   ;每显示一个字符,就改变一次颜色
		add bx, 2
		loop s
int9ret:pop es
		pop cx
		pop bx
		pop ax
		iret
int9end:nop
code ends
end start
	
		

; int指令的调用
	; 1、标志寄存器入栈:	
		; pushf
	; 2、将TF、IF标志位置为0
		; TF和IF在标志寄存器的第8和第9位置(最低位是0)
		; pushf
		; pop ax
		; and ah, 11111100b
		; push ax
		; popf	;将处理后的标志寄存器的值通过栈传回标志寄存器
		; 3、CS、IP入栈
		; 4、IP=n*4, CS=n*4+2 
	; 3、上面的两部可以合为一个操作:
		; call dword ptr ds:[0]
		; 相当于:
			; push CS
			; push IP
			; IP=(ds)*16+0 
			; CS=(ds)*16+2

实验结果:
这里写图片描述

最后

以上就是和谐煎蛋为你收集整理的王爽《汇编语言》第三版 编写INT9中断例程的全部内容,希望文章能够帮你解决王爽《汇编语言》第三版 编写INT9中断例程所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部