实验16完成了,代码都做了注释,最后结果如下面四个图所示。
安装一个新的int 7ch中断例程,为显示输出提供如下功能子程序。
清屏
设置前景色
设备背景色
向上滚动一行
(1)ah寄存器传递功能号:0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行
(2)对于1 2 号功能,用al传送颜色值,al={1,2,3,4,5,6,7}
assume cs:code,ss:stack,ds:data
data segment
ARRAY db 87h,99h,0ah,0cdh,0DCH
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,128 ;初始化栈
call cpy_new_int7cH ;拷贝中断到内存安全位置0:7e00h
call set_new_int7CH ;设置中断向量表
mov al,4 ;传递一个颜色
mov ah,2 ;功能号
int 7CH ;调用新中断
mov ax,4c00h
int 21h
;==============================================================
;设置中断向量表
;============================================
set_new_int7CH:
mov bx,0
mov es,bx
cli ;屏蔽中断
mov word ptr es:[7ch*4],7e00h
mov word ptr es:[7ch*4+2],0
sti ;允许中断
ret
;=====================================================================
;拷贝中断
;=====================================================================
cpy_new_int7cH:
mov bx,cs
mov ds,bx
mov si,OFFSET new_int7CH ;设置源位置
mov bx,0
mov es,bx
mov di,7e00h ;设置目的位置
mov cx,OFFSET new_int7CH_end - OFFSET new_int7CH ;设置拷贝长度
cld ;按字节复制ds:[si]->es:[di]
rep movsb
ret
;===========================================================================
;设置新中断
;===================================================================
new_int7CH:
jmp newInt7ch
TABLE dw OFFSET clear_screen - OFFSET new_int7CH + 7e00h ;找到每个子函数的入口地址
dw OFFSET set_pre_screen - OFFSET new_int7CH + 7e00h
dw OFFSET set_back_screen - OFFSET new_int7CH + 7e00h
dw OFFSET set_screen - OFFSET new_int7CH + 7e00h
newInt7ch:
;清理屏幕
;call clear_screen
;设置前景色
;call set_pre_screen
;设置背景色
;call set_back_screen
;向上1一行
; call set_screen
push ax ;al ah 有
push bx
push es
mov bx,0
mov es,bx ;es:[0]
mov bl,ah ;bl = ah 功能号
add bx,bx ;功能号*2 = 对应的子程序入口地址。
add bx,OFFSET TABLE - OFFSET new_int7CH + 7e00h ;OFFSET TABLE - OFFSET new_int7CH是算出table的入口地址
call word ptr es:[bx] ; 调用对应的功能子程序
pop es
pop bx
pop ax
iret
;=======================================
;屏幕上移动一行
;==============================================
set_screen:
push bx
push cx
push es
push si
push di
mov bx,0b800h
mov es,bx
mov ds,bx
mov cx,80*24 ;80个字型数据
mov si,160
mov di,0
cld
rep movsw
mov bx,160*24
mov cx,80
mov dx,0700h
setRowBlank:
mov es:[bx],dx ;清空最后一行
add bx,2 ;
loop setRowBlank
pop di
pop si
pop es
pop cx
pop bx
ret
;============================================
;设置背景色
;========================================================
set_back_screen:
push ax
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,1
mov cl,4
shl al,cl ;al左移4个位置,设置背景色
mov cx,2000
setBackScreen:
and byte ptr es:[bx],10001111B
or es:[bx],al
add bx,2
loop setBackScreen
pop es
pop cx
pop bx
pop ax
ret
;====================================
;设置前景色
;======================================
set_pre_screen:
push ax
push bx
push cx
push es
mov bx,0b800h
mov es,bx ;0
mov bx,1 ;
mov cx,2000
setPreScreen:
and byte ptr es:[bx],11111000b ;1111
or es:[bx],al
add bx,2
loop setPreScreen
pop es
pop cx
pop bx
pop ax
ret
;=====================================================
;清屏就是让屏幕上每个字符都为0700h
;=====================================================
clear_screen:
push bx
push cx
push dx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov dx,0700h ;清屏幕
mov cx,2000
clearScreen:
mov es:[bx],dx
add bx,2
loop clearScreen
pop es
pop dx
pop cx
pop bx
ret
new_int7CH_end:
nop
;;===================================
code ends
end start