汇编语言实验16安装一个新的int 7ch中断例程

安装一个新的int 7ch中断例程,为显示输出提供如下功能子程序
(1)清屏;
(2)设置前景色;
(3)设置背景色;
(4)向上滚动一行。
入口参数说明如下
(1)用ah寄存器传递功能号:0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行;
(2)对于1, 2号功能,用al传送颜色值,(al) E {0,1,2,3,4,5,6,7}

assume cs:code

code segment
	start:	mov ax,0
			mov es,ax
			mov ax,200h
			mov di,ax
			
			mov ax,cs
			mov ds,ax
			mov ax,offset int7c
			mov si,ax
			
			mov cx,offset int7c_end-offset int7c
			
			cld 
			rep movsb	; 复制代码到内存中
			
			cli		; 避免受到可屏蔽中断的影响
			mov ax,0	; 设置中断向量表
			mov ds,ax
			mov word ptr ds:[07ch*4],200h
			mov word ptr ds:[07ch*4+2],0
			sti

			mov ax,4c00h
			int 21h
			
	int7c:	jmp short set
  			; 这里要注意,在安装程序中的sub1是一串数据,在中断例程安装在0:200h中时
  			; 如果仍然按照第十六章那样设置,以是无法成功调用子程序的,因为主程序运行完毕以后
  			; 主程序所占的内存可能会被其他内容覆盖,所以我们要把子程序安装在中断例程之后的内存中
  			; 当然这样会存在一个问题,如果中断例程并没有安装在0:200处,则table中的值也要相应改动
  			; 至于为什么子程序中的sub1s,sub2s以及loop指令还能正常工作,是因为这是基于位移的跳转
  			; 即在主程序中,相应的loop/jmp指令已经编译为回退/前进xx字节的指令,因此不会受位置移动的影响

  			table	dw sub1-int7c+200h,sub2-int7c+200h,sub3-int7c+200h,sub4-int7c+200h
  	
  	set:	push bx
  	
  			cmp ah,3	; 判断功能号是否大于3
  			ja sret
  			mov bl,ah
  			mov bh,0
  			add bx,bx	; 根据ah提供的功能号找到对应子程序在table中的偏移
  			
  			push cs
  			pop ds
  			call word ptr [bx+200h+2]	; 调用
  			
  	sret:	pop bx
  			iret
  			
  	; 各个子程序的实现
	; 清屏
	sub1:	push bx
			push cx
			push es
			
			mov bx,0b800h
			mov es,bx
			mov bx,0
			
			mov cx,2000
   sub1s:	mov byte ptr es:[bx],' '
   			add bx,2
   			loop sub1s
   			
   			pop es
   			pop cx
   			pop bx
   			ret
   			
   			
   	; 设置前景色
    sub2:	push bx
			push cx
			push es
   			
			mov bx,0b800h
			mov es,bx
			mov bx,1
			mov cx,2000
			
   sub2s:	and byte ptr es:[bx],11111000b	; 第0、1、2位与前景色的有关
   											; 其他位和1与运算,保持不变
   			or es:[bx],al	;将前3位设置为对应的颜色
   			add bx,2	; 奇数地址表示字符属性
   			loop sub2s
   			
   			pop es
   			pop cx
   			pop bx
   			ret
   			
   	; 设置背景色
    sub3:	push bx
			push cx
			push es
			mov cl,4
			shl al,cl
   			
			mov bx,0b800h
			mov es,bx
			mov bx,1
			mov cx,2000
			
   sub3s:	and byte ptr es:[bx],10001111b	; 第4、5、6位与背景色的有关
   											; 其他位和1与运算,保持不变
   			or es:[bx],al	;设置为对应的颜色
   			add bx,2	; 奇数地址表示字符属性
   			loop sub3s
   			
   			pop es
   			pop cx
   			pop bx
   			ret
   			
   	; 向上滚动一行
   	sub4:	push cx
   			push si
   			push di
   			push es
   			push ds
   			
   			mov si,0b800h
   			mov es,si
   			mov ds,si
   			mov si,160		; ds:si指向第n+1行
   			mov di,0		; es:di指向第n行
   			cld
   			mov cx,24
   			
   sub4s:	push cx
   			mov cx,160
   			rep movsb		; 复制
   			pop cx
   			loop sub4s
   			
   			mov cx,80
   			mov si,0
   sub4s1:	mov byte ptr [160*24+si],' '	;最后一行清空
   			add si,2
   			loop sub4s1
   			
   			pop ds
   			pop es
   			pop di
   			pop si
   			pop cx
   			ret		

int7c_end:	nop
code ends
end start

测试子程序0

assume cs:code
code segment
	start:	mov ah,0 ;mas mov al,6
	       int 7ch			
	       mov  ax,4c00h
	       int 21h
code ends
end start

测试子程序1

assume cs:code
code segment
	start:	mov ah,
		mov al,6
		int 7ch
			
		mov  ax,4c00h
		int 21h
code ends
end start

测试子程序2

assume cs:code
code segment
	start:	mov ah,2
		mov al,6
		int 7ch
			
		mov  ax,4c00h
		int 21h
code ends
end start

测试子程序3

assume cs:code

code segment
	start:	mov ah,3
		int 7ch
			
		mov  ax,4c00h
		int 21h
code ends
end start

发布日期:

所属分类: 编程, 编程语言 标签:


没有相关文章!