利用int 9 中断程序,在屏幕中间依次显示a-z,按下esc改变显示的颜色
程序如下所示
assume cs:code
stack segment
db 128 dup(0)
stack ends
data segment
dw 0,0
data ends
code segment
start:
mov ax,stack ;设置栈
mov ss,ax
mov sp,128
mov ax,data ;设置数据段
mov ds,ax
mov ax,0
mov es,ax
push es:[9*4] ;将原来的int 9的中断程序的入口地址保存在ds:0和ds:2的单元中
pop ds:[0]
push es:[9*4+2]
pop ds:[2]
mov word ptr es:[9*4],offset int9 ;在中断向量当中设置新的int 9的中断程序的入口地址
mov es:[9*4+2],cs
;循环显示a-z的所有字符
mov ax,0b800h
mov es,ax
mov ah,'a'
s: mov byte ptr es:[160*12+40*2],ah
call delay ;延迟调用
inc ah
cmp ah,'z' ;比较有没有到z
jna s ;不高于z,就跳到s处
mov ax,0 ;将中断向量表中的int 9中断程序的入口恢复为原来的地址
mov es,ax
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
mov ax,4c00h
int 21h
delay:
push ax ;使用cup循环空运行,实现延迟时间的作用
push dx ;让dx做高位,ax为低位,然后这样去减
mov dx,1h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0
jne s1
pop dx
pop ax
ret
;自定义int 9中断程序
int9:
push ax ;保存临时变量
in al,60h ;从端口60h读出键盘的输入
pushf ;下面要用用于call模拟原先的int9后的
pushf ;用于修改IF=0、TF=0 操作
pop bx
and bh,11111100b
push bx
popf
call dword ptr ds:[0]
;调用完这个模拟的int9后,会执行iret操作
;会先popf出第一次pushf的值
cmp al,1
jne int9ret ;al!=1就返回
inc byte ptr es:[160*12+40*2+1] ;将属性值加1,改变了颜色
int9ret:
pop ax
iret
code ends
end start
程序执行结果,可以看到第二行一行的z是蓝色的,就是按了esc输出的结果