安装一个新的int 7ch中断例程,为显示输出提供如下功能子程序:
(1)清屏 (2)设置前景色 (3)设置背景色 (4)向上滚动一行
贴上网上一段代码,写下自己的注释:
data segment
str1 db "First: You will can't look us!",'$'
str2 db "Second: Because we are in Row 1, now!",'$'
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
lea dx,str1 ;lea指令是将str1的偏移地址存放在dx寄存器中
mov ah,9 ;显示第一个字符串str1
int 21h
mov bh,0
mov dh,1
mov dl,0
mov ah,2
int 10h ;将光标置为第1行、第0列[行、列下标都从0开始]。
lea dx,str2
mov ah,9
int 21h ;显示第二个字符串str2
mov ah,1 ;从设置前景色开始进行循环
mov al,1 ; 颜色属性初始为1(1为蓝色)
func: push ax
cmp ah,3
ja quit
call setscreen
call delay ;延迟
pop ax
inc ah ;功能号加1
inc al ;颜色属性加1后变为绿色
jmp short func
quit: mov ah,0 ;跳出循环后则清屏
call setscreen
mov ax,4c00h
int 21h
setscreen proc near ;设置屏幕函数的子程序
jmp short set
table: dw sub1,sub2,sub3,sub4 ;存放四个功能子程序偏移地址的表结构
set: push ax
push bx
cmp ah,3
ja sret
mov bl,ah
mov bh,0
add bx,bx
call word ptr table[bx] ;调用对应的功能子程序
sret: pop bx
pop ax
ret
setscreen endp
delay proc near ;延迟函数,让CPU执行15000000h次减法。
push ax
push dx
mov dx,1500h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0
jne s1
pop dx
pop ax
ret
delay endp
sub1 proc near ;清屏的子过程定义
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,2000
sub1s: mov byte ptr es:[bx],0
;mov byte ptr es:[bx+1],0 ;是否也清除屏幕的背景色(随便你)
add bx,2
loop sub1s
pop es
pop cx
pop bx
ret
sub1 endp
sub2 proc near ;设置前景色的子过程定义
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
sub2 endp
sub3 proc near ;设置背景色的子过程定义
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1
mov cl,4
shl al,cl
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
sub3 endp
sub4 proc near ;向上滚动一行的子过程定义
push cx
push di
push ds
push es
push si
mov si,0b800h
mov ds,si
mov es,si
mov si,160
mov di,0
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 si
pop es
pop ds
pop di
pop cx
ret
sub4 endp
code ends
end start
str1 db "First: You will can't look us!",'$'
str2 db "Second: Because we are in Row 1, now!",'$'
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
lea dx,str1 ;lea指令是将str1的偏移地址存放在dx寄存器中
mov ah,9 ;显示第一个字符串str1
int 21h
mov bh,0
mov dh,1
mov dl,0
mov ah,2
int 10h ;将光标置为第1行、第0列[行、列下标都从0开始]。
lea dx,str2
mov ah,9
int 21h ;显示第二个字符串str2
mov ah,1 ;从设置前景色开始进行循环
mov al,1 ; 颜色属性初始为1(1为蓝色)
func: push ax
cmp ah,3
ja quit
call setscreen
call delay ;延迟
pop ax
inc ah ;功能号加1
inc al ;颜色属性加1后变为绿色
jmp short func
quit: mov ah,0 ;跳出循环后则清屏
call setscreen
mov ax,4c00h
int 21h
setscreen proc near ;设置屏幕函数的子程序
jmp short set
table: dw sub1,sub2,sub3,sub4 ;存放四个功能子程序偏移地址的表结构
set: push ax
push bx
cmp ah,3
ja sret
mov bl,ah
mov bh,0
add bx,bx
call word ptr table[bx] ;调用对应的功能子程序
sret: pop bx
pop ax
ret
setscreen endp
delay proc near ;延迟函数,让CPU执行15000000h次减法。
push ax
push dx
mov dx,1500h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0
jne s1
pop dx
pop ax
ret
delay endp
sub1 proc near ;清屏的子过程定义
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,2000
sub1s: mov byte ptr es:[bx],0
;mov byte ptr es:[bx+1],0 ;是否也清除屏幕的背景色(随便你)
add bx,2
loop sub1s
pop es
pop cx
pop bx
ret
sub1 endp
sub2 proc near ;设置前景色的子过程定义
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
sub2 endp
sub3 proc near ;设置背景色的子过程定义
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1
mov cl,4
shl al,cl
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
sub3 endp
sub4 proc near ;向上滚动一行的子过程定义
push cx
push di
push ds
push es
push si
mov si,0b800h
mov ds,si
mov es,si
mov si,160
mov di,0
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 si
pop es
pop ds
pop di
pop cx
ret
sub4 endp
code ends
end start
此程序通过循环[标号func处]来自动完成各功能号的调用。此程序实现的效果依次是:设置前景色[此时(ah)=1、(al)=1],设置背景色[此时(ah)=2、(al)=2],向上滚动一行[此时(ah)=3],清屏[此时(ah)=0]。程序之所以首先显示两个字符串,是为了辅助测试程序的四个子功能(尤其是向上滚