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 Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|