安装一个新的int 7ch中断例程,为显示输出提供如下功能子程序
(1)清屏;
(2)设置前景色;
(3)设置背景色;
(4)向上滚动一行。
入口参数说明如下
(1)用ah寄存器传递功能号:0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行;
(2)对于1, 2号功能,用al传送颜色值,(al) E {0,1,2,3,4,5,6,7}
assume cs:code code segment start: mov ax,0 mov es,ax mov ax,200h mov di,ax mov ax,cs mov ds,ax mov ax,offset int7c mov si,ax mov cx,offset int7c_end-offset int7c cld rep movsb ; 复制代码到内存中 cli ; 避免受到可屏蔽中断的影响 mov ax,0 ; 设置中断向量表 mov ds,ax mov word ptr ds:[07ch*4],200h mov word ptr ds:[07ch*4+2],0 sti mov ax,4c00h int 21h int7c: jmp short set ; 这里要注意,在安装程序中的sub1是一串数据,在中断例程安装在0:200h中时 ; 如果仍然按照第十六章那样设置,以是无法成功调用子程序的,因为主程序运行完毕以后 ; 主程序所占的内存可能会被其他内容覆盖,所以我们要把子程序安装在中断例程之后的内存中 ; 当然这样会存在一个问题,如果中断例程并没有安装在0:200处,则table中的值也要相应改动 ; 至于为什么子程序中的sub1s,sub2s以及loop指令还能正常工作,是因为这是基于位移的跳转 ; 即在主程序中,相应的loop/jmp指令已经编译为回退/前进xx字节的指令,因此不会受位置移动的影响 table dw sub1-int7c+200h,sub2-int7c+200h,sub3-int7c+200h,sub4-int7c+200h set: push bx cmp ah,3 ; 判断功能号是否大于3 ja sret mov bl,ah mov bh,0 add bx,bx ; 根据ah提供的功能号找到对应子程序在table中的偏移 push cs pop ds call word ptr [bx+200h+2] ; 调用 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 ; 设置前景色 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位与前景色的有关 ; 其他位和1与运算,保持不变 or es:[bx],al ;将前3位设置为对应的颜色 add bx,2 ; 奇数地址表示字符属性 loop sub2s pop es pop cx pop bx ret ; 设置背景色 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 ; 第4、5、6位与背景色的有关 ; 其他位和1与运算,保持不变 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 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 int7c_end: nop code ends end start
测试子程序0
assume cs:code code segment start: mov ah,0 ;mas mov al,6 int 7ch mov ax,4c00h int 21h code ends end start
测试子程序1
assume cs:code code segment start: mov ah, mov al,6 int 7ch mov ax,4c00h int 21h code ends end start
测试子程序2
assume cs:code code segment start: mov ah,2 mov al,6 int 7ch mov ax,4c00h int 21h code ends end start
测试子程序3
assume cs:code code segment start: mov ah,3 int 7ch mov ax,4c00h int 21h code ends end start