TSR. Ошибка при выгрузке

Тема в разделе "WASM.ASSEMBLER", создана пользователем AExc, 15 май 2005.

  1. AExc

    AExc New Member

    Публикаций:
    0
    Регистрация:
    15 май 2005
    Сообщения:
    1
    Имеется TSR. Отлавливаются прерывания INT09 и INT10. При попытке выгрузки вылетает по недопустимой операции. Вроде, всё нормально, т.к. старые обработчики сохраняются, затем восстанавливаются, но по прерыванию после выгрузки TSR переход осуществляется в непотребное место (что-то типа 00F0:FFFF). Пробовал изголяться по-всякому: выгружать из INT2F, записывать старые адреса в файл, однако проклятая ... ничего не ... Вот исходник (вариант с файлом). Может, там имеется какой-либо серьёзный недочёт?
    Код (Text):
    1.  
    2. cseg segment                                  
    3.     assume cs:cseg, ds:cseg, ss:cseg, es:cseg
    4.     org 100h                                  
    5.   Begin:
    6.     jmp  Init
    7.       old_10h_off dw 0
    8.       old_10h_seg dw 0
    9.       old_09h_off dw 0
    10.       old_09h_seg dw 0
    11. Int_10h_proc proc
    12.     ...
    13.     cmp  ax, ...
    14.     jne  
    15.     ...
    16.     iret                      
    17.   Run_:
    18.     jmp  dword ptr cs:[old_10h_off]
    19. Int_10h_proc endp
    20.  
    21. Int_09h_proc proc
    22.     cli
    23.     cmp  ax, ...
    24.     jne  Test_2
    25.     ...
    26.   Test_2:
    27.     pushf        
    28.     call dword ptr cs:[old_09h_off]
    29.     ...
    30.     sti          
    31.     iret
    32. Int_09h_proc endp
    33.  
    34. ;далее несколько процедур
    35. ...
    36.   Init:
    37.     nop
    38.     mov  ax, ...                     ; проверка на повторную загрузку.
    39.     int  10h
    40.     cmp  ax, ...
    41.     jne  Next_step2
    42.   ; при загруженном резиденте
    43.     ...
    44.     call Get_cmd                     ; получаем командную строку
    45.     cmp  al, '/'
    46.     je   Unload_Res                  ; при /u выгружаем
    47.     ...
    48.     jmp  Success_cmd_i
    49.   Unload_Res:
    50.     call Free_res
    51.     jmp  No_cmdline
    52.   Success_cmd_i:
    53.     push dx
    54.     mov  ah, 9                       ; здесь программа уже загружена
    55.     mov  dx, offset Mess_memory      ; выводим сообщение
    56.     int  21h
    57.     ...
    58.   No_cmdline:
    59.     mov  ax, 4C00h                   ; выход в DOS
    60.     int  21h
    61.   ; при незагруженном резиденте
    62.   Next_step2:
    63.     ...
    64.     call Get_cmd                     ; получаем командную строку
    65.     jnc  Success_cmd                 ; сообщение
    66.     cmp  al, '/'
    67.     je   Already_load
    68.     ...
    69.     jmp  Success_cmd
    70.   Already_load:
    71.     mov  ah, 9
    72.     lea  dx, Mess_err
    73.     int  21h
    74.     jmp  No_cmdline
    75.   Success_cmd:
    76.     ...
    77.     mov  es, word ptr cs:[2Ch]       ; получаем сегмент окружения DOS
    78.     mov  ah, 49h                     ; функция освобождения памяти
    79.     int  21h                         ; освобождаем память
    80.     mov  word ptr cs:[0F6h], 0       ; cs:[0F6h] - адрес буфера
    81.     ...
    82.   ; переопределение INT9
    83.     mov  ax, 3509h
    84.     int  21h                         ; сохраняем старый обработчик INT9
    85.     mov  word ptr cs:[old_09h_off],bx       ; cмещение
    86.     mov  word ptr cs:[old_09h_seg],es       ; и cегмент
    87.     mov  word ptr cs:[off09], bx
    88.     mov  word ptr cs:[seg09], es
    89.     mov  ax, 2509h                   ; записываем новый обработчик
    90.     lea  dx, Int_09h_proc            ; Int_09h_proc
    91.     int  21h
    92.   ; переопределение INT10
    93.     mov  ax, 3510h
    94.     int  21h                         ; сохраняем старый обработчик INT10
    95.     mov  word ptr cs:[old_10h_off], bx
    96.     mov  word ptr cs:[old_10h_seg], es
    97.     mov  word ptr cs:[off10], bx
    98.     mov  word ptr cs:[seg10], es
    99.     mov  ax, 2510h                   ; записываем новый обработчик
    100.     lea  dx, Int_10h_proc            ; Int_10h_proc
    101.     int  21h
    102.   End_init:
    103.    
    104.     mov  ah, 3Ch                     ; создаём новый файл
    105.     xor  cx, cx
    106.     mov  dx, offset n_file
    107.     int  21h
    108.     mov  bx, ax
    109.     mov  ah, 40h
    110.     mov  cx, 8
    111.     push cs
    112.     pop  ds
    113.     mov  dx, offset off10
    114.     int  21h
    115.     mov  ah, 3Eh                     ; закрываем файл
    116.     int  21h
    117.    
    118.     ;mov  ax, 3100h              ; при этом варианте ошибка всё равно возникает
    119.     ;mov  dx, (end_s-Begin+10Fh)/16
    120.     ;int  21h
    121.     lea  dx, Init
    122.     int  27h                         ; сохранение в памяти резидента
    123.  off10 dw 0
    124.  seg10 dw 0
    125.  off09 dw 0
    126.  seg09 dw 0
    127. ;===================================================================== =======
    128. ;=== Получение имени файла из аргумента командной строки ====================
    129. ;===================================================================== =======
    130. Get_cmd proc
    131.     ...
    132. Get_cmd endp                        
    133.  
    134. ;эти процедуры привожу полностью, т.к., возможно, в них баг
    135. ;===================================================================== =======
    136. ;=== Удаление резидента из памяти ===========================================
    137. ;===================================================================== =======
    138. Free_res proc
    139.     push cx
    140.     push dx
    141.     push es
    142.     push ds
    143.    
    144.     mov  dx, offset n_file
    145.     mov  ah, 3Dh
    146.     xor  al, al
    147.     int  21h
    148.     mov  bx, ax
    149.     xor  cx, cx
    150.     xor  dx, dx
    151.     mov  al, 0
    152.     mov  ah, 42h
    153.     int  21h
    154.     mov  ah, 3Fh
    155.     mov  cx, 8
    156.     mov  dx, offset off10
    157.     int  21h
    158.    
    159.     call Unload_proc
    160.  
    161.     mov  dx, offset Mess_remove      ; выводим сообщение о выгрузке
    162.     mov  ah, 9
    163.     int  21h
    164.  
    165.     pop  ds
    166.     pop  es
    167.     pop  dx
    168.     pop  cx
    169.     ret                              ; выход
    170. Free_res endp
    171.  
    172. ;===================================================================== =======
    173. ;=== Процедура выгрузки =====================================================
    174. ;===================================================================== =======
    175. Unload_proc proc
    176.     nop
    177.     push ds
    178.     push es
    179.     push dx
    180.     mov  ax, 2509h
    181.     mov  dx, word ptr seg09
    182.     mov  ds, dx
    183.     mov  dx, word ptr off09
    184.     int  21h
    185.     mov  ax, 2510h
    186.     mov  dx, word ptr seg10
    187.     mov  ds, dx
    188.     mov  dx, word ptr off10
    189.     int  21h
    190.     ;push cs
    191.     ;pop  es
    192.     ;mov  ah, 49h
    193.     ;int  21h
    194.     pop  dx
    195.     pop  es
    196.     pop  ds
    197.     ret
    198. Unload_proc endp
    199.  
     
  2. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Я не очень смотрел твой код ;) Но все же скажу, что обычно делают так: в выгружающем коде посылают сообщение резиденту и тот самовыгружается. Пример выгрузки резидента в аттаче.

    [​IMG] 1102344386__Virt_key.asm