安装新的int 9中断例程

时间:2023-03-09 15:38:28
安装新的int 9中断例程

body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-child(2n){background-color: #f8f8f8;} div, p, blockquote{line-height: 1em; margin-top: 0.5em; margin-bottom: 0.5em}

任务:安装一个新的 int 9 中断例程,功能:在 DOS 下,按 F1 键后改变当前屏幕的显示颜色,其他的键照常处理。
1、改变屏幕的显示颜色;
改变从 B8000 开始的 4000 个字节中的所有奇地址单元中的内容,当前屏幕的显示颜色即发生改变。
           mov ax , 0b800h
        mov es , ax
        mov bx , 1
        mov cx , 2000
s:        inc byte ptr es:[bx]
        add bx , 2
        loop s
2、其他键照常处理;
可以调用原 int 9 中断处理程序,来处理其他的键盘输入。
3、原 int 9 中断例程的入口地址保存;
因为在编写的新 int 9 中断例程中要调用原 int 9 中断例程处理键盘输入的其他细节,所以,要保存原 int 9 中断例程的入口地址。因为安装程序返回后地址将丢失,所以可以选择将地址保存在 0:200 单元处。这个地方是开辟给中断向量表的,其他程序不能访问,但是向量表用不了这么多。
4、新 int 9 中断例程的安装
可以从 0:204 处开始安装
assume cs:code
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
        mov si , offset int9        ; 安装新中断例程地址
        mov di , 204h
        mov cx , offset int9end- offset int9
        cld
        rep movsb
        push es:[9*4]        ; 保存原int 9中断例程入口地址
        pop es:[200h]
        push es:[9*4+2]
        pop es:[202h]
        cli        ; 关可屏蔽中断
        mov word ptr es:[9*4] , 204h        ; 设置新的int 9中断例程入口地址
        mov word ptr es:[9*4+2] , 0
        sti        ; 开可屏蔽中断
        mov ax , 4c00h
        int 21h
int9:        push ax
        push bx
        push cx
        push es
        in al , 60h
        pushf
        call dword ptr cs:[200h]        ; 当9号中断执行的时候(CS)=0
;这里调用原int 9中断例程,我们事先把原9号中断例程的入口地址存放在0:[200]~0:[204]
;之所以要调用原9号中断例程,是因为还要处理其它细节
;eg:扫描码加上ASCII放到键盘输入缓冲区,状态字节放到0040:17
        cmp al , 3bh        ;  F1 键的扫描码是 3bh
        jne int9ret
        mov ax , 0b800h
        mov es , ax
        mov bx , 1
        mov cx , 2000        ; 25*80=2000 一页可以存2000个字符,每个字符要存一个字符属性,25*160=4000
s:      inc byte ptr es:[bx]        ; 循环修改显示页面能存储的所有字符的显示属性
        add bx , 2
        loop s
int9ret:        pop es
        pop cx
        pop bx
        pop ax
        iret
int9end:        nop
code ends
end start
安装新的int 9中断例程
安装新的int 9中断例程

assume cs:code
stack segment
        db 128 dup (0)
stack ends
code segment
start:        mov ax , stack
        mov ss , ax
        mov sp , 128
        mov ax , 4c00h
        int 21h
code ends
end start
安装新的int 9中断例程