编写包含多个功能子程序的中断例程

这里写图片描述

assume cs:code,ss:stack 

stack segment
    db 128 dup (0)
stack ends

code segment
start:
    mov ax,stack
    mov ss,ax
    mov sp,128
    push cs
    pop ds
    mov ax,0
    mov es,ax ;在0:204存放程序
    mov si,offset int7chStart;ds:[si] ;中断例程首地址
    mov di,204H;es:[di]要放中断例程
    mov cx,offset int7chEnd-offset int7chStart;程序长度
    cld;进程程序的拷贝
    rep movsb

    push es:[7CH*4]
    pop es:[200H]
    push es:[7CH*4+2]
    pop es:[202H];保存原来的中断矢量表int 7ch的处理程序的地址
    mov word ptr es:[7CH*4],204H
    mov word ptr es:[7CH*4+2],0;改变中断处理程序的地址
    mov ah,2; 设置功能为2,设置背景色
    mov al,4; 设置颜色
    int 7CH
    push es:[200H]
    pop es:[7CH*4]
    push es:[202H]
    pop es:[7CH*4+2];恢复原来中断向量的表当中的int7ch 中断例程的入口地址
    mov ax,4C00H
    int 21H
org 204H;在汇编语言源程序的开始通常都用一条ORG伪指令来实现规定程序的起始地址,如果这里不设置执行的时候table的偏移地址就找不对了
int7chStart:
    jmp short install
    table dw sub1,sub2,sub3,sub4
    install: 
        push bx
        cmp ah,3 ;判断功能号是不是大于3
        ja installRet
        mov bl,ah
        mov bh,0
        add bx,bx ;bx+bx
        call word ptr table[bx];根据功能号去寻找寻找程序的偏移
    installRet: 
        pop bx
        iret
    sub1:;清屏对应的功能号为0
        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:;设置前景子程序对应的功能号为1
        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,3位所以与上的相应位为0
            or es:[bx],al;al传送的是颜色值
            add bx,2
            loop sub2s
        pop es
        pop cx
        pop bx
        ret
    sub3:;设置背景色,对应的功能号为2
        push bx
        push cx
        push es
        mov cl,4
        shl al,cl;将al左移4位,因为要设置的是第4、5、6位,al最大取7,所以要进行移动
        mov bx,0B800H
        mov es,bx
        mov bx,1
        mov cx,2000
        sub3s: 
            and byte ptr es:[bx],10001111B;这里就是要去改变4、5、6位做准备
            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]刚开始指向的是第一行
        mov di,0;es:[di]刚开始指向第0行
        cld
        mov cx,24;共复制24行
        sub4s: 
            push cx
            mov cx,160;cx是为长度
            rep movsb;每次操作si和di递增,不需要再设置行号和列数 
            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
int7chEnd:
    nop
code ends
end start

执行效果如下所示,背景色为红色
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值