第一点要注意的是原int 9例程用 iret 语句返回,从栈里弹出三个数据。我们用call 语句调用int 9 例程,需要也入栈一个寄存器值 pushf,保持对应。
修改中断向量表时,用 cli 和 sti 语句禁用中断,和恢复中断。防止程序出错。
assume cs:code,ds:data,ss:stack
stack segment
db 128 dup (0)
stack ends
data segment
db 4 dup (0)
data ends
code segment
main:
mov ax,stack
mov ss,ax
mov sp,128;设置栈段
mov ax,data
mov ds,ax;设置数据段,保存原int9中断例程入口地址
mov ax,0
mov es,ax
cli
mov ax,es:[9 * 4];IP
mov ds:[0],ax
mov ax,es:[9 * 4 + 2];CS,保存原int9入口
mov ds:[2],ax
sti
mov word ptr es:[9 * 4],offset int9
mov word ptr es:[9 * 4 + 2],cs;int9 指向新段
mov ax,0b800h
mov es,ax
mov ah,'a'
show:
mov es:[160 * 12 + 40 * 2],ah
call delay
inc ah
cmp ah,'z'
jna show
mov ax,0
mov es,ax
cli
push ds:[0]
pop es:[9 * 4]
push ds:[2]
pop es:[9 * 4 + 2]
sti
mov ax,4c00h
int 21h
delay:
push ax
push dx
mov dx,10h
mov ax,0
godelay:
sub ax,1
sbb dx,0
cmp ax,0
jne godelay
cmp dx,0
jne godelay
pop dx
pop ax
ret
int9:
push ax
push bx
push es
in al,60h
pushf
pushf
pop bx
and bh,11111100b
push bx
popf
call dword ptr ds:[0];以call调用,int9以iret返回
cmp al,1
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es:[160 * 12 + 2 * 40 + 1]
int9ret:
pop es
pop bx
pop ax
iret;重点,以iret返回中断掉用
code ends
end main
测试效果如下:
谢谢阅读