正在加载……
专注、离线、切勿分心
任务:安装一个新的 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
  // 这是按下3次 F1 键后的显示效果;执行了一次 1.exe 再输入执行 1.exe 程序会卡死,因为第二次执行,本来代码中保存系统原来的9号中断例程入口地址现在变成保存我们新改写的中断例程,后面int9中断调用原9号中断例程处理键盘输入调用不到了,不能处理我们的键盘输入,所以系统崩溃,得重启DOS
 // 这是显示一页后又回车加入新的行,再执行F1变色……


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

posted on 2017-12-11 15:30  正在加载……  阅读(1042)  评论(0编辑  收藏  举报