Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/25: Рейтинг темы: голосов - 25, средняя оценка - 4.88
1 / 1 / 0
Регистрация: 05.12.2010
Сообщений: 34

Выгрузка резидента из обработчика прерывания

22.04.2012, 19:04. Показов 5198. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Вопрос такой: Как в программе выгрузить из памяти резидент , в конце обработчика прерывания int 09h(в данном случае)????
т.е цель: выводить время и сразу же выгружать программу

Весь день пытался сделать, максимум восстановливал обработчики, но память не освобождалась. Вариант с выгрузкой в нерезидентной части программы сделал. Вот код.


Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
code    segment                          ; определение кодового сегмента
        assume  cs:code,ds:code          ; CS и DS указывают на сегмент кода
        org     100h        ; размер PSP для COM программы
    .8086
    P386N
start:  jmp     load                     ; переход на нерезидентную часть
        old     dd  ?                    ; адрес старого обработчика 
        buf     db  ' 00:00:00 ',0       ; шаблон для вывода текущего времени
        old_2Fh DD ?
        insflag db ?
        m1 db 'the programm installed',10,13,'$'
        m2 db 'the programm already installed',10,13,'$'
        m5 db 'the programm has been deleted',10,13,'$'
 
decode  proc                             ; процедура заполнения шаблона
        mov     ah,  al                  ; преобразование двоично-десятичного 
        and     al,  15                  ; числа в регистре AL
        shr     ah,  4                   ; в пару ASCII символов
        add     al,  '0'
        add     ah,  '0'
        mov     buf[bx + 1],  ah         ; запись ASCII символов
        mov     buf[bx + 2],  al         ; в шаблон
        add     bx,  3      
        ret                              ; возврат из процедуры
decode  endp                             ; конец процедуры 
;--------------------------------------------------------------------
; обработчик прерывания 2Fh
; ---------------------------------------------------------------------
new_2Fh PROC
 
cmp AH, 0CCh ; проверка номера
jne pass_2Fh ; не наш номер -> выход
 
cmp AL, 0 ; функция проверки на установку?
jne check1 ; нет -> проверяем функцию выгрузки
mov al,0ffh ; да -> программа типа загружена
iret
 
check1: 
;проверка на функцию выгрузки  
    cmp al,01h
    je un
    iret
    
pass_2Fh: jmp dword ptr CS:[old_2Fh]
 
un:
     pusha
     push es 
     push ds 
     ;восстанавливаем вектор 09h
     mov ax,2509h
     mov dx,word ptr cs:[old]
     mov ds,word ptr cs:[old+2]
     int 21h
    ;восстанавливаем вектор 2Fh
     mov ax,252fh
     mov dx,word ptr cs:[old_2Fh]
     mov ds,word ptr cs:[old_2Fh+2]
     int 21h
     
     mov es,cs:2ch ; получим из PSP адрес собственного 
     mov ah,49h ; окружения резидента и выгрузим его 
     int 21h ;  
    
     push cs ; выгрузим теперь саму программу 
     pop es ; 
     mov ah,49h ; 
     int 21h ; 
     
     pop ds ;
     pop es
     popa
     
    iret ; 
 
new_2Fh ENDP
 
;-------------------------------------------------------------------------
Обработчик прерывания 09h
;------------------------------------------------------------------------
clock   proc   
 
                          ; процедура обработчика прерываний от таймера
        pushf                            ; создание в стеке структуры для IRET
        call    cs:old                   ; вызов старого обработчика прерываний
    push    ds                       ; сохранение модифицируемых регистров
    push    es
    push    ax
    push    bx
    push    cx
    push    dx
    push    di
        push    cs
        pop     ds
            
    in  al, 60h     ;прочитаем код из клавиатуры
    cmp al, 57h     ;F11 ?
    jne @@5
        mov     ah,  2                   ; функция BIOS для получения текущего времени
        int     1Ah                      ; прерывание BIOS
 
        xor     bx,  bx                  ; настройка BX на начало шаблона
        mov     al,  ch                  ; в AL - часы
        call    decode                   ; вызов процедуры заполнения шаблона - часы
        mov     al,  cl                  ; в AL - минуты
        call    decode                   ; вызов процедуры заполнения шаблона - минуты
        mov     al,  dh                  ; в AL - секунды
        call    decode                   ; вызов процедуры заполнения шаблона - секунды 
 
        mov     ax,  0B800h              ; настройка AX на сегмент видеопамяти
        mov     es,  ax                  ; запись в ES значения сегмента видеопамяти
        xor     di,  di                  ; настройка DI на начало сегмента видеопамяти
        xor     bx,  bx                  ; настройка BX на начало шаблона
        mov     ah,  1Bh                 ; атрибут выводимых символов
@@1:    mov     al,  buf[bx]             ; цикл для записи символов шаблона в видеопамять
        stosw                            ; запись очередного символа и атрибута
        inc     bx                       ; инкремент указателя на символ шаблона
        cmp     buf[bx],  0              ; пока не конец шаблона,
        jnz     @@1                      ; продолжать запись символов
 
@@5:    pop     di                       ; восстановление модифицируемых регистров
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        pop     es
        pop     ds
        jmp dword ptr cs:old         ;на старый вектор                            ; возврат из обработчика
    
    iret
clock   endp                             ; конец процедуры обработчика
end_clock:                               ; метка для определения размера резидентной
                                         ; части программы
load:
;проверка загруженна и программа?
    mov AX, 0CC00h
    int 2Fh
    mov insflag, AL
    
    cmp insflag, 0FFh ; программа загружена?
    jne inst ; нет - загружаем, да - выгружаем
;сообщаем пользователю что программа уже загружена
    mov DX, offset m2
    mov AH, 09h
    int 21h
; посылаем функцию выгрузки  
    mov ax,0cc01h
    int 2fh 
;сообщаем что наша программа выгружена 
    mov ah,09h 
    mov dx,offset m5 
    int 21h 
    jmp exit
    
inst:
;int 2fh
        mov AX, 352Fh           ; получить вектор
        int 21h                 ; прерывания 2Fh
        mov word ptr old_2Fh, BX    ; сохранение полученного
        mov word ptr old_2Fh+2, ES  ; вектора
        mov DX, offset new_2Fh  ; установка нового вектора
        mov AX, 252Fh ;
        int 21h ;
 
;int 09h
        mov     ax,  3509h               ; получение адреса старого обработчика
        int     21h                      ; прерываний от таймера
        mov     word ptr old,  bx        ; сохранение смещения обработчика
        mov     word ptr old + 2,  es    ; сохранение сегмента обработчика
        mov     ax,  2509h               ; установка адреса нашего обработчика
        mov     dx,  offset clock        ; указание смещения нашего обработчика
        int     21h                      ; вызов DOS
    ;вывод сообщения о том что программа загружена
        pusha
        pushf
        mov DX,offset m1
        mov AH, 09h
        int 21h
        popf
        popa
        
        mov     ax,  3100h               ; функция DOS завершения резидентной программы
        mov     dx, (end_clock - start + 10Fh) / 16 ; определение размера резидентной
                                                    ; части программы в параграфах
        int     21h                      ; вызов DOS
    
        exit:
         mov ax,4c00h ;выходим
         int 21h ; 
code    ends                             ; конец кодового сегмента
        end     start                    ; конец программы
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
22.04.2012, 19:04
Ответы с готовыми решениями:

Заменить вектор прерывания int 9h
Здравствуйте! Мне нужно заменить вектор прерывания int 9h, чтобы выполнялись следующие действия: первый раз нажимаем клавишу -...

Извлечение сегмента кода в процессе работы резидентного обработчика прерывания
Здравствуйте. Имеется TSR-программа для ДОС, отображающая регистры процессора. Вопрос в том, можно ли узнать сегмент кода (CS) любого...

Выгрузка резидента по нажатию клавиши.
Как организовать выгрузку резидента по нажатию клавиши? Желательно на примере.

5
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
22.04.2012, 20:43
Кхе... INT 09h - таймер? Не знал, не знал...
Насчёт INT 2Fh/мультиплекса и проверки на "уже загружен" - идея оказалась мертворождённой из-за громоздкости реализации.
А рабочие примерчики с таймером есть здесь, выгрузка резидента тоже.
0
1779 / 757 / 153
Регистрация: 03.06.2009
Сообщений: 5,940
23.04.2012, 08:30
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    push    0       ;сегмент векторов прерываний
    pop es
    mov ax,word ptr CS:Old09    ; восстановление векторов прерываний
    mov es:[24h],ax
    mov ax,word ptr CS:Old09+2
    mov es:[26h],ax
    mov ax,word ptr CS:Old2d
    mov es:[0b4h],ax
    mov ax,word ptr CS:Old2d+2
    mov es:[0b6h],ax
    mov ax,CS:[2Ch] ; сегмент переменных окружения
    dec ax      ;его MCB
    mov es,ax
    mov es:[1],word ptr 0   ;Записываем в MCB блока Owner=0, значит блок свободен
    mov ax,CS       ; сегмент самого резидента
    dec ax              ;его MCB
    mov es,ax
    mov es:[1],word ptr 0   ;Записываем в MCB блока Owner=0, значит блок свободен
Это можно сделать прямо из прерывания.
1
116 / 136 / 0
Регистрация: 15.04.2012
Сообщений: 1,031
23.04.2012, 09:18
Можно, переместить адрес в резидентную область, а после обработчика восстанавливать вектор прерывания, и вызывать int 20h. Должно сработать.
0
1 / 1 / 0
Регистрация: 05.12.2010
Сообщений: 34
24.04.2012, 11:05  [ТС]
Всем спасибо за ответы ! Что подсказали, ничего не получилось(. на данный момент имеется код обработчика,в котором восстанавливаются вектора, а вот программа не выгружается. Код выгружающий саму программу под комментами. Вопрос: почему этот код не срабатывает)? И как всё таки добиться выгрузки программы из этого прерывания? в чем фишка?)

Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
clock   proc   ;обработчик прерывания 09h
        pushf                            ; создание в стеке структуры для IRET
        call    cs:old                   ; вызов старого обработчика прерываний
    push    ds                       ; сохранение модифицируемых регистров
    push    es
    push    ax
    push    bx
    push    cx
    push    dx
    push    di
        push    cs
        pop     ds
        
    in  al, 60h     ;прочитаем код из клавиатуры
    cmp al, 57h     ;F11 ?
    je @@5
    
        pop     di                       ; восстановление модифицируемых регистров
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        pop     es
        pop     ds
        jmp dword ptr cs:old         ;на старый вектор                            ; возврат из обработчика
    
@@5:    mov     ah,  2                   ; функция BIOS для получения текущего времени
        int     1Ah                      ; прерывание BIOS
 
        xor     bx,  bx                  ; настройка BX на начало шаблона
        mov     al,  ch                  ; в AL - часы
        call    decode                   ; вызов процедуры заполнения шаблона - часы
        mov     al,  cl                  ; в AL - минуты
        call    decode                   ; вызов процедуры заполнения шаблона - минуты
        mov     al,  dh                  ; в AL - секунды
        call    decode                   ; вызов процедуры заполнения шаблона - секунды 
 
        mov     ax,  0B800h              ; настройка AX на сегмент видеопамяти
        mov     es,  ax                  ; запись в ES значения сегмента видеопамяти
        xor     di,  di                  ; настройка DI на начало сегмента видеопамяти
        xor     bx,  bx                  ; настройка BX на начало шаблона
        mov     ah,  1Bh                 ; атрибут выводимых символов
@@1:    mov     al,  buf[bx]             ; цикл для записи символов шаблона в видеопамять
        stosw                            ; запись очередного символа и атрибута
        inc     bx                       ; инкремент указателя на символ шаблона
        cmp     buf[bx],  0              ; пока не конец шаблона,
        jnz     @@1                      ; продолжать запись символов
 
        in al,61h ; восстановим разрешение прерываний 
        or al,80h ; от клавиатуры 
        out 61h,al 
        and al,7fh 
        out 61h,al 
        mov al,20h 
        out 20h,al 
 
        pop     di                       ; восстановление модифицируемых регистров
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        pop     es
        pop     ds      
    ;восстанавливаем вектор 09h
     mov ax,2509h
     mov dx,word ptr cs:[old]
     mov ds,word ptr cs:[old+2]
     int 21h
    ;восстанавливаем вектор 2Fh
     mov ax,252fh
     mov dx,word ptr cs:[old_2Fh]
     mov ds,word ptr cs:[old_2Fh+2]
     int 21h    
     ; mov es,cs:2ch ; получим из PSP адрес собственного 
     ; mov ah,49h ; окружения резидента и выгрузим его 
     ; int 21h ;  
    
     ; push cs ; выгрузим теперь саму программу 
     ; pop es ; 
     ; mov ah,49h ; 
     ; int 21h ;         
    iret
clock   endp                             ; конец процедуры обработчика
Добавлено через 16 часов 12 минут
Короче, задача сводится к - выгрузке резидентной программы по нажатию нужной клавиши.
Нашёл пример кода, по нажатию на Ctrl + Х выгружает программу из памяти.
http://www.kpdev.ru/sources-info.php?sirec=3120 Задача под номером 12.
!НО
при выгрузке выводится сообщение, а память (с смотрю по строке свободной памяти в досе) остается занятой программой. Зато после включения , например, маленькой программки(вывод строки "hello!"), в досе показывает что резидента в памяти уже нет.
Чем это можно объяснить?!
0
116 / 136 / 0
Регистрация: 15.04.2012
Сообщений: 1,031
24.04.2012, 12:23
Ничего, все правильно. ДОС никогда не очищает сегмент сразу после выгрузки. Смотрел в DOS. Но в памяти уже нет. Следующая программа запишется на место резидента и затрет его. Все. Порядок.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.04.2012, 12:23
Помогаю со студенческими работами здесь

Не работает эмуляция обработчика прерывания Print Screne
Задание такое - эмуляция обработчика прерывания Print Screen (INT 5) c выводом копии экрана в файл\ на принтер. Вот мой код: ...

Выгрузка прерывания из памяти
Доброго времени суток! программа не выгружается из памяти, просмотрел много чего в интернете, но, к сожалению, так и не получилось. ...

удаление резидента
Подскажите кто знает программу, чтобы удалять резиденты в оперативке. А то написать-то написал, а удалить знаю тока через volkov commander....

Выход из обработчика прерывания
Задача: По прерыванию (нажатие кнопки) нужно покинуть рабочий цикл и передать управление некой подпрограмме. Обработчик прерывания: ...

Выход из обработчика прерывания
Есть обработчик прерывания, который проверяет состояние кнопки и в зависимости от состояния кнопки переходит в определенный адрес. Как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru