Имеется TSR. Отлавливаются прерывания INT09 и INT10. При попытке выгрузки вылетает по недопустимой операции. Вроде, всё нормально, т.к. старые обработчики сохраняются, затем восстанавливаются, но по прерыванию после выгрузки TSR переход осуществляется в непотребное место (что-то типа 00F0:FFFF). Пробовал изголяться по-всякому: выгружать из INT2F, записывать старые адреса в файл, однако проклятая ... ничего не ... Вот исходник (вариант с файлом). Может, там имеется какой-либо серьёзный недочёт? Code (Text): cseg segment assume cs:cseg, ds:cseg, ss:cseg, es:cseg org 100h Begin: jmp Init old_10h_off dw 0 old_10h_seg dw 0 old_09h_off dw 0 old_09h_seg dw 0 Int_10h_proc proc ... cmp ax, ... jne ... iret Run_: jmp dword ptr cs:[old_10h_off] Int_10h_proc endp Int_09h_proc proc cli cmp ax, ... jne Test_2 ... Test_2: pushf call dword ptr cs:[old_09h_off] ... sti iret Int_09h_proc endp ;далее несколько процедур ... Init: nop mov ax, ... ; проверка на повторную загрузку. int 10h cmp ax, ... jne Next_step2 ; при загруженном резиденте ... call Get_cmd ; получаем командную строку cmp al, '/' je Unload_Res ; при /u выгружаем ... jmp Success_cmd_i Unload_Res: call Free_res jmp No_cmdline Success_cmd_i: push dx mov ah, 9 ; здесь программа уже загружена mov dx, offset Mess_memory ; выводим сообщение int 21h ... No_cmdline: mov ax, 4C00h ; выход в DOS int 21h ; при незагруженном резиденте Next_step2: ... call Get_cmd ; получаем командную строку jnc Success_cmd ; сообщение cmp al, '/' je Already_load ... jmp Success_cmd Already_load: mov ah, 9 lea dx, Mess_err int 21h jmp No_cmdline Success_cmd: ... mov es, word ptr cs:[2Ch] ; получаем сегмент окружения DOS mov ah, 49h ; функция освобождения памяти int 21h ; освобождаем память mov word ptr cs:[0F6h], 0 ; cs:[0F6h] - адрес буфера ... ; переопределение INT9 mov ax, 3509h int 21h ; сохраняем старый обработчик INT9 mov word ptr cs:[old_09h_off],bx ; cмещение mov word ptr cs:[old_09h_seg],es ; и cегмент mov word ptr cs:[off09], bx mov word ptr cs:[seg09], es mov ax, 2509h ; записываем новый обработчик lea dx, Int_09h_proc ; Int_09h_proc int 21h ; переопределение INT10 mov ax, 3510h int 21h ; сохраняем старый обработчик INT10 mov word ptr cs:[old_10h_off], bx mov word ptr cs:[old_10h_seg], es mov word ptr cs:[off10], bx mov word ptr cs:[seg10], es mov ax, 2510h ; записываем новый обработчик lea dx, Int_10h_proc ; Int_10h_proc int 21h End_init: mov ah, 3Ch ; создаём новый файл xor cx, cx mov dx, offset n_file int 21h mov bx, ax mov ah, 40h mov cx, 8 push cs pop ds mov dx, offset off10 int 21h mov ah, 3Eh ; закрываем файл int 21h ;mov ax, 3100h ; при этом варианте ошибка всё равно возникает ;mov dx, (end_s-Begin+10Fh)/16 ;int 21h lea dx, Init int 27h ; сохранение в памяти резидента off10 dw 0 seg10 dw 0 off09 dw 0 seg09 dw 0 ;===================================================================== ======= ;=== Получение имени файла из аргумента командной строки ==================== ;===================================================================== ======= Get_cmd proc ... Get_cmd endp ;эти процедуры привожу полностью, т.к., возможно, в них баг ;===================================================================== ======= ;=== Удаление резидента из памяти =========================================== ;===================================================================== ======= Free_res proc push cx push dx push es push ds mov dx, offset n_file mov ah, 3Dh xor al, al int 21h mov bx, ax xor cx, cx xor dx, dx mov al, 0 mov ah, 42h int 21h mov ah, 3Fh mov cx, 8 mov dx, offset off10 int 21h call Unload_proc mov dx, offset Mess_remove ; выводим сообщение о выгрузке mov ah, 9 int 21h pop ds pop es pop dx pop cx ret ; выход Free_res endp ;===================================================================== ======= ;=== Процедура выгрузки ===================================================== ;===================================================================== ======= Unload_proc proc nop push ds push es push dx mov ax, 2509h mov dx, word ptr seg09 mov ds, dx mov dx, word ptr off09 int 21h mov ax, 2510h mov dx, word ptr seg10 mov ds, dx mov dx, word ptr off10 int 21h ;push cs ;pop es ;mov ah, 49h ;int 21h pop dx pop es pop ds ret Unload_proc endp
Я не очень смотрел твой код Но все же скажу, что обычно делают так: в выгружающем коде посылают сообщение резиденту и тот самовыгружается. Пример выгрузки резидента в аттаче. 1102344386__Virt_key.asm