欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-07 09:08:13
...

安装一个新的int 7ch中断例程,为显示输出提供如下功能子程序。

  1. 清屏
  2. 设置前景色
  3. 设置背景色
  4. 向上滚动一行
入口参数说明如下:
1.用ah寄存器传递功能号:0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行
2.对于1、2号功能,用al传送颜色值,al的取值范围为1-7.

注意

这题用书上的方法我卡了好久。原因在于用table标号时,code段从start开始,在setscreen前面已经有语句了,导致table的定位出现了问题。我看有别的blog的代码把start标号开头那一段放到最后也能运行,但我试了好久也没成功。这里使用了org语法。

org 200h:表示指定200h,后面的程序或者代码从这个地址开始分配。

例如:
org 200h
mov ax,bx
;mov指令的偏移地址就是200h

int7ch中断代码

assume cs:code
code segment

;----安装setscreen程序到0:200h处----
start:
	mov ax,cs
	mov ds,ax
	mov si,offset setscreen
	
	mov ax,0
	mov es,ax
	mov di,200h	;int7ch中断安装在0:200处	
	mov cx,offset setscreen_end - offset setscreen
	
	cld
	rep movsb
	
;----把0:200入口地址写入int7ch中断向量表----
	mov ax,0
	mov es,ax
	mov word ptr es:[7ch*4],200h
	mov word ptr es:[7ch*4+2],0
	
	mov ax,4c00h
	int 21h

;----把setscreen安装到原int7----
org 200h	;设置setscreen的偏移地址
setscreen:
	table dw sub1,sub2,sub3,sub4
	jmp short set
	
	set:
	push bx
	push ax
	cmp ah,3
	ja sret
	mov bx,0
	mov bl,ah
	add bx,bx
	
	call word ptr table[bx]
	sret:
	pop ax
	pop bx
	iret	;中断返回
	
;----子程序1:清屏----
	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
	
;----子程序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	;把奇字节的第0、1、2位清零
	or es:[bx],al	;用or操作把012三位设置为我们想要的颜色
	add bx,2
	loop sub2s
	
	pop es
	pop cx
	pop bx
	ret

;----子程序3:设置背景色----
	sub3:
	push bx
	push cx
	push es
	push ax
	
	mov cl,4
	shl al,cl	;al用来传送颜色,al的值为0-7,设置背景色是456位,要把al左移4位、
	mov bx,0b800h
	mov es,bx
	mov bx,1	;显存中的基地址为属性字节
	mov cx,2000
	
	sub3s:
	and byte ptr es:[bx],10001111b	;第456位先置0,其他位不变
	or es:[bx],al	;es:[bx]和al相或,设置颜色
	add bx,2
	loop sub3s
	
	pop ax
	pop es
	pop cx
	pop bx
	ret
	
;----子程序4:向上滚动1行----
	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行,整屏就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
setscreen_end:nop


code ends
end start

1.子程序1-清零测试:

代码:

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

运行结果:
汇编语言 | 实验16 编写包含多个功能子程序的中断例程

2.子程序2-设置前景色测试:

代码:

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

运行结果:
汇编语言 | 实验16 编写包含多个功能子程序的中断例程

3.子程序3-设置背景色测试:

代码:

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

运行结果:
汇编语言 | 实验16 编写包含多个功能子程序的中断例程

4.子程序4-向前滚动一行测试

代码:

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

运行结果:
汇编语言 | 实验16 编写包含多个功能子程序的中断例程