第一点要注意的是原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
测试效果如下:
谢谢阅读