;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
;在显示的过程中,按下“ESC”键后,改变显示的颜色。
assume cs:code,ss:stack,ds:data
data segment
db 0,0,0,0
data ends
stack segment
db 128 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,128
mov ax,0
mov es,ax ;中断向量表的段地址为0
push es:[9*4] ;将原来 int 9 中断例程的指令的
pop es:[200h]
push es:[9*4+2] ;ip保存到0:200,cs保存到0:202
pop es:[202h]
mov ax,cs ;将新int 9中断例程的入口地址
mov ds,ax
mov si,offset int9
mov di,204h
mov cx,offset int9end - offset int9
cld
rep movsb
cli ;将IF置0,屏蔽其他可屏蔽的中断
mov word ptr es:[9*4],204h ;设置新的中断例程
mov word ptr es:[9*4+2],0
sti ;恢复IF置1
mov ax,0b800h
mov es,ax
mov ah,'a'
s: mov es:[160*12+40*2],ah
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0 ;中断例程的入口地址恢复为
mov es,ax ;原来的入口地址
push es:[200h]
pop es:[9*4]
push es:[202h]
pop es:[9*4+2]
mov ax,4c00h
int 21h
delay: push ax
push dx
mov dx,1000h
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
;cmp dx,0ff0h
cmp dx, 0 ; 都说了,你的延时太短
jne s1
pop dx
pop ax
ret
;--------以下为新的 int 9 中断例程--------------------
int9: push ax
push bx
push es
;这里
mov ax, 0
mov es, ax
in al,60h ;从60h端口读入数据
pushf
;pop bx
pushf
pop bx ;这里
and bx,1111110011111111b
push bx
popf
call dword ptr es:[200h] ;对int指令进行模拟,调用原来的int 9中断例程
cmp al,1+80h
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es:[160*12+40*2+1] ;属性增加1,改变颜色
int9ret: pop es
pop bx
pop ax
iret
int9end: nop
code ends
end start