汇编语言----实验16--编写包含多个功能子程序的中断例程

关于王爽老师的汇编语言实验16

题目如下:

安装一个int7c中断例程,未显示输出提供如下子程序

1、清屏  2、设置前景色 3、设置背景色 4、向上滚动一行

用ah寄存器传递功能号:0清屏 1 设置前景色  2 表示背景色  3向上滚动一行

对于2、3号子程序,用al传送颜色值 al  范围是 [   0 ,  7  ]


代码如下:

assume cs:code
code segment
start:
	;复制代码
	mov ax,0 
	mov es,ax
	mov di,200h
	mov ax,cs
	mov ds,ax
	mov si,offset setscreen 
	mov cx,offset setscreenend-offset setscreen
	cld
	rep movsb
;设置中断向量表
	mov word ptr es:[7ch*4],200h
	mov word ptr es:[7ch*4+2],0

;用ah传递功能号,al传送颜色

	mov ah,1 
	mov al,2
	int 7ch
	mov ax,4c00h
	int 21h
	ORG 200h ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!因为要重新设置,
        	;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!中断前sub1的地址和中断后的不一样
setscreen:
		jmp short set 
		
	table  dw sub1 ,sub2 ,sub3 ,sub4 
	
	set: push bx
		 
		 cmp ah,3	;判断功能号是否大于3----容错性
		 ja sret
		 mov bl,ah 
		 mov bh,0
		 add bx,bx 		;根据ah中的功能号计算调用对应子程序在table表
						;中的偏移
		 call word ptr table[bx]		;调用对应的子程序
		 
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 
		
;设置前景色,将显存中奇地址的属性字节的第0、1、2 位		
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
		or es:[bx],al
		add bx,2 
		loop sub2s
		
		pop es
		pop cx
		pop bx
		ret 
;设置背景色  奇地址的4、5、6位改	
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
		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				;共复制24行
		
sub4s:	push cx
		mov cx,160 
		rep movsb			;复制
		pop cx
		loop sub4s
		 
		mov si,0 	
		mov cx,80 
sub4s1:	 
		mov byte ptr [160*24+si],' '		;最后一行清空
		inc si
		inc si
		loop sub4s1
		
		pop ds
		pop es
		pop di 
		pop si
		pop cx
		ret
	
setscreenend:nop	

code ends
	end start 	
		
		

初次写完之后发现运行完没有显示,然后搜寻答案发现网上的要么是加上了25行,要么就是在30行修改了偏移地址

刚开始怎么都想不通,后来想想,是因为table[bx],等于cs:0[bx],又由于这里的bx是相对于自己的程序而言的,这不是我们需要的

 因为程序是从0200h处开始的,所以我们的偏移量应该从这里开始



所以为了纠正,在程序最前边加上ORG 200h,意思是以后的程序的偏移地址从200h开始

比如 jmp short set的偏移地址就是 200h,后面的以此类推


因为子程序在中断例程下面,所以还有一种方法,用sub1-setscreen+200h,这个是sub1的偏移地址,其余以此类推

你可能感兴趣的:(汇编)