我考虑过调试,但是在TSR程序上这样做似乎是不可能的。我已经尝试将数据段推入代码段并保存原始的数据段以便稍后恢复,但是即使在恢复了数据段之后也会导致机器挂起。
section .text ;Code Section
org 100h ;DOS Executable Start
mov ah,35h ;Get Interrupt Vector
mov al,28h ;Of Interrupt 28h
int 21h ;Call DOS Kernel
push cs ;Push Code Segment
pop ds ;Onto Data Segment
mov [oldseg],es ;Save Old Interrupt Vector Segment
mov [oldoff],bx ;Save Old Interrupt Vector Offset
mov ah,25h ;Set Interrupt Vector
mov dx,resstart ;To Resstart
int 21h ;Call DOS Kernel
mov dx,resend ;Set Data Offset to Resend
sub dx,resstart ;Subtract Resstart
shr dx,4h ;Shift Right 4 Bits for Paragraph
inc dx ;One Extra Paragraph for PSP
mov ah,31h ;Terminate and Stay Resident
xor al,al ;Return Code
int 21h ;Call DOS Kernel
resstart: ;Resident Code Start
push ax ;Save AX
push es ;Save ES
push di ;Save DI
push cx ;Save CX
push ds ;Save DS
push dx ;Save DX
mov ah,00h ;Set Video Mode
mov al,13h ;To Mode 13h
int 10h ;Call BIOS Video
mov ax,0A000h ;VGA Segment
mov es,ax ;Stored in ES
xor di,di ;VGA Offset in DI
mov cx,0FA00h ;Fill Entire Screen
mov al,09h ;With Light Blue Color
rep stosb ;Repeat Store AL at ES:DI
mov ah,25h ;Set Interrupt Vector
mov al,28h ;Of Interrupt 28h
mov ds,[oldseg] ;Restore Old Interrupt Vector Segment
mov dx,[oldoff] ;Restore Old Interrupt Vector Offset
int 21h ;Call DOS Kernel
pop dx ;Restore DX
pop ds ;Restore DS
pop cx ;Restore CX
pop di ;Restore DI
pop es ;Restore ES
pop ax ;Restore AX
iret ;Return and Restore Flags
resend: ;Resident Code End
section .data
oldseg dw 0 ;Old Interrupt Vector Segment
oldoff dw 0 ;Old Interrupt Vector Offset
在返回原始中断向量地址并将新的中断向量地址设置为"resstart"后,程序应该终止并保持驻留状态。此后,中断28h会自动触发,因为DOS没有其他事情要做,这会依次运行我的中断处理程序。
中断处理程序将视频模式设置为13h,尝试用浅蓝色填充整个屏幕,恢复原始的中断28h处理程序,恢复所有涉及到的寄存器和标志,并返回到DOS。执行此程序不会产生任何结果,甚至系统也不会停机。但单独运行设置视频模式13h和用蓝色填充整个屏幕的部分却可以正常工作。