;程序名称:p16
;任务:安装一个新的int 7ch中断例程,为显示输出提供的子程序功能为,
; (1)清屏;(2)设置前景色;(3)设置背景色;(4)向上滚动一行
;参数:(ah)=功能号,0表示清屏,1表示设置前景色,2表示设置背景色,
;3表示向上滚动一行;对于2、3号功能,用al传送颜色值,
;(al)∈{0,1,2,3,4,5,6,7}
assume cs:code
code segment
start:
call Install_7ch ;安装新编int 7ch
mov ax,0 ;下面代码为手动测试安装结果及功能
mov ds,ax ;测试每项,均需重新编译和链接生成新的.exe
mov ah,1 ;手动设置功能号,现为1号前景色
mov al,00000110b ;手动设置颜色,现为黄色
cmp ah,3
ja ovr
mov bl,ah
mov bh,0
add bx,bx
mov bx,204h[bx] ;从0:204h~20bh读取入口偏移地址
mov word ptr ds:[7ch*4],bx ;将入口偏移地址写入中断向量表
mov word ptr ds:[7ch*4].2,0 ;置0,确保入口段地址正确
int 7ch ;引发int 7ch中断,运行指定的新编7ch子程序
mov word ptr ds:[7ch*4],0 ;结束前抹去痕迹,复原为0
ovr: mov ax,4c00h
int 21h
;- - - - - - - - - - - - - - - - - - - - - -
;Install_7ch子程序
;任务:将上述子程序全部安装,记录入口地址,为int 7ch调用作准备
;上述子程序安装后,入口地址存放位置如下:
; 0号,置清屏 0:204h~205h
; 1号,置前景色 0:206h~207h
; 2号,置背景色 0:208h~209h
; 3号,置向上滚动一行 0:20ah~20bh
Install_7ch:
push ax
push bx
push cx
push ds
push es
push di
push si
jmp short In7ch
T dw sub1,sub2,sub3,sub4,sub4end ;相关标号地址入表
In7ch: mov bx,cs
mov ds,bx
mov bx,0
mov es,bx
mov si,T[bx] ;设置ds:si指向源地址
mov di,20ch ;设置es:di指向目标地址
Inr: mov es:[bx].204h,di ;将各子程序入口偏移地址存于0:204h~20bh中
mov ax,T[bx].2
sub ax,T[bx] ;相减得各子程序代码的字节数量
mov cx,ax ;设置各子程序传递字节的循环次数
cld ;正向,则si、di与循环同步累计增长,不必另设
rep movsb ;从源地址向目标地址传递代码字节
add bx,2 ;T表中寻址增2
cmp bx,8 ;判断是否完成4个安装
jne Inr ;未完成则继续安装
pop si
pop di
pop es
pop ds
pop cx
pop bx
pop ax
ret
;- - - - - - - - - - - - - - - - - - - - - -
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
iret
;- - - - - - - - - - - - - - - - - - - - - -
sub2: ;设置前景色子程序
push cx
push bx
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 bx
pop cx
iret
;- - - - - - - - - - - - - - - - - - - - - -
sub3: ;设置背景色子程序
push bx
push cx
push es
mov cl,4 ;因为(al)∈{0,1,2,3,4,5,6,7},
shl al,cl ;而sub3处理外景色,故需左移,低位变高位
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
iret
;- - - - - - - - - - - - - - - - - - - - - -
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 ;共复制24行
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
iret
sub4end: nop
code ends
end start
- [游客] 为啥简版的int 13h之后不用 jmp 也行。 08/31 00:14
- [hky987654321] 是的,按压F1的次数 >=15 ,有“按下“→”键会出现光斑落在年份的百位数上”的现象。 这与缓冲 08/09 11:12
- [游客] 为什么多次按F1后,按下“→”键会出现光斑落在年份的百位数上? 08/02 21:42
- [游客] 懂了。 07/30 10:54
- [hky987654321] -1就是FFh。用-1兼济了ffff:0和简洁的数据分隔这二者的需要。 [bp-2],是因为刚进入 07/29 11:43
- [游客] 也看不懂[bp-2] 07/12 10:49
- [游客] 不懂-1 07/09 17:55
- [游客] 16位现在只有教学意义,看一眼就好。 04/13 00:46
- [游客] 没搞错吧,课程2才351b 03/09 18:01
- [游客] 没想到实验14只用13条代码! 03/02 15:46