Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

MOV WORD PTR OLD_VEC + 2, AX. MOV WORD PTR ES:[BX + 2], Resident. 11.4 Вызов старого обработчика прерывания. JMP CS:OLD_VEC




MOV WORD PTR OLD_VEC + 2, AX

; установка нового значения вектора прерывания

CLI

MOV WORD PTR ES: [BX], OFFSET KbProc

MOV WORD PTR ES: [BX + 2], Resident

STI

; завершение программы и загрузка резидентной части

MOV DX, Code

SUB DX, Data

ADD DX, 10H

MOV AH, 31H

MOV AL, 0

INT 21H

Code ENDS

 

Stac2 SEGMENT PARA STACK

DB 128 DUP (? )

Stac2 ENDS

END Start

 

Последний пример будет использоваться в дальнейшем для добавления к программе типа EXE других элементов структуры резидентной программы.

 

11. 4 Вызов старого обработчика прерывания

Вызов старого обработчика прерывания может выполняться как перед основным кодом резидентной части, так и после него. Конкретное расположение вызова обработчика зависит от того, следует ли выполнить какие-либо действия до того, как старый обработчик выполнит стандартные действия или нет. Если старый обработчик вызывается до основного кода резидентной части, то этот вызов выполняется так, как было показано в предыдущих примерах. Если необходимо вызвать старый обработчик после кода резидентной части, то это можно выполнить либо таким же способом, либо используя команду JMP, как показано в следующем примере:

OLD_VEC DD?

. . .         

MyProc PROC

. . .

JMP CS: OLD_VEC

MyProc ENDP

 

Следует отметить, что такой вызов должен выполняться в самом конце процедуры обработки прерывания, так как управление на код, расположенный за этим вызовом, уже не вернется. При таком вызове состояние стека должно быть таким же, как и при входе в процедуру обработки прерывания.

При написании процедуры проверки на повторную загрузку возникает необходимость каким-либо образом узнать, загружена ли уже в памяти резидентная часть программы или нет. При написании процедуры выгрузки резидентной части программы из памяти, резидентной части требуется как-то передать команду на выгрузку из памяти. Во всех этих случаях необходимо организовать связь нерезидентной части программы с уже загруженной в память копией резидентной части программы. Связь можно организовывать, применив какое-либо прерывание. При этом перехватывается вектор этого прерывания, и резидентная часть содержит процедуру его обработки. Тогда нерезидентная часть вызывает это прерывание, обработка которого попадает к резидентной части, а резидентная часть должна, во-первых, определить, что ее вызвала «своя» программа, а, во-вторых, дать знать «своей» программе, что резидентная часть уже загружена. Также возникает вопрос, какой номер прерывания выбрать для организации связи. В MS-DOS существует специальное прерывание 2FH, которое называется мультиплексным прерыванием и служит для связи процессов. Для того чтобы резидентная программа узнала о том, что ее вызвала «своя» программа, нерезидентная часть программы должна записать в какие-либо регистры какие-либо уникальные значения, которые потом резидентная часть программы должна будет проверить. Если проверяемые резидентной частью значения совпадают с теми, которые должны быть, резидентная часть возвращает в каких-либо регистрах «ответ» тоже в виде каких-либо уникальных значений. Если значения не совпадают с требуемыми, то резидентная часть должна передать управление по цепочке старому обработчику, который также может вызвать еще более старый обработчик и т. д. Таким образом, организуется интерфейс нерезидентной части с резидентной. После того, как нерезидентная часть вызвала мультиплексное прерывание, она проверяет «ответ» резидентной части для проверки «своей» резидентной части. Если проверяемые нерезидентной частью значения совпали с требуемыми, то можно с уверенностью сказать, что резидентная копия программы уже загружена в память.

Следующий пример демонстрирует программу, которая перехватывает вектор прерывания 2FH и проверяет, загружена ли резидентная часть программы в память или нет. Если резидентная часть уже загружена, программа завершается, если нет, то загружает резидентную часть и завершается.

CODE SEGMENT

ASSUME CS: CODE, DS: CODE

ORG 100H

Start:

JMP Init

OLD_2FH DD?

New2FH PROC

CMP AX, 1234H           ; проверка на “свою” программу

JNE Exit

CMP DX, 9876H

JNE Exit

MOV AX, 4321H          ; запись в регистры ответа

MOV DX, 6789H

IRET                                ; возврат из процедуры

Exit:     

JMP CS: OLD_2FH           ; передача управления по цепочке

New2FH ENDP

Init:

MOV AX, 1234H          ; запись в регистры

MOV DX, 9876H          ; уникальных значений

INT 2FH               ; вызов мультиплексного

                                       ; прерывания

CMP AX, 4321H           ; сравнение возвращенных

JNE Load                   ; значений (ответа)

CMP DX, 6789H           ; с нужными

JNE Load

MOV AX, 4C00H          ; завершение программы, если

INT 21H                    ; проверяемые значения совпали с требуемыми

Load:

MOV BX, 2FH * 4    ; вычисление смещения

XOR AX, AX

MOV ES, AX            ; настройка ES на таблицу

MOV AX, ES: [BX]    ; векторов прерываний

; сохранение значения старого вектора прерывания

MOV WORD PTR OLD_2FH, AX

MOV AX, ES: [BX + 2]

MOV WORD PTR OLD_2FH + 2, AX

; установка нового значения вектора прерывания

CLI

MOV WORD PTR ES: [BX], OFFSET New2FH

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...