MCB (Memory Control Block) является блоком DOS, описывающим каждый распределенный участок памяти. Как правило, MCB всегда строится перед PSP исполняемой программы и для "окружения" программы. Рассмотрим формат MCB.
Таблица 1. Формат MCB
Смещение | Длина | Содержимое |
---|---|---|
00h | 1 | тип блока: 'M' (4Dh) - промежуточный блок; 'Z' (5Ah) - последний блок |
01h | 2 | сегмент владельца блока, 0 - свободный блок |
03h | 2 | количество параграфов в блоке |
05h | 3 | резерв |
08h | 9 | имя программы формата ASCIZ для блоков с PSP |
Размер блока - 16 байт.
Для определения первого блока цепочки можно воспользоваться недокументированной функцией MSDOS 52h, которая в es:bx возвращает list of list, в es:[bx-2] находится сегмент первого MCB блока.
Описатель начала цепочки UMB блоков находится по адресу 9FFF:0000 (недокументировано).
В процессе работы могут возникать некоторые события. События бывают синхронные и асинхронные. Синхронные события - это те, которые происходят в процессе выполнения программы всегда в одном и том же месте. Асинхронные события - это те, которые происходят независимо от работы программы. К синхронным событиям относятся вызовы системы DOS, BIOS. К асинхронным событиям относятся вызовы обработчиков нажатий клавиши на клавиатуре, поступление символа по каналу связи и т.п. Асинхронные прерывания - это, обычно, аппаратные прерывания.
Первые 1024 байта - это таблица векторов (Interupt Table), содержащая для каждого из 256 векторов двухсловный указатель на обработчик. При вызове соответствующего прерывания контроллер прерываний сохраняет в стеке регистр флагов, устанавливает запрет прерываний с большим или равным номером IRQ (для аппаратных прерываний) сохраняет в стеке CS, IP и передает управление обработчику прерываний. Обработчик должен выполнить необходимые действия и вернуть управление командой IRET. В некоторой литературе ошибочно написано о необходимости разрешить прерывания перед возвратом, - этого делать не следует, т.к. после разрешения прерывания, перед инструкцией IRET начинается обработка следующего прерывания стоящего в очереди, и есть высокая вероятность получения сообщения:
Internal Stack Overflow. System halted.
Возможно два способа обработки событий своим обработчиком:
К полной замене приходится прибегать довольно редко. Обычно это используется для написания обработчика "пустых" векторов. Встраивание в цепочку обработчиков прерывания используют все программные драйверы, которым необходимо получить управление при возникновении тех или иных событий.
Встраивание в цепочку обработчиков прерывания происходит по следующей схеме:
Иногда необходимо получить управление как до старого обработчика, так и после него. Это производится следующим образом:
PUSHF [Предобработка] CALL FAR [Адрес старого обработчика] PUSHF [Постобработка] POPF RETF 2 ; с сохранением флагов старого обработчика
Команды Pushf и Call Far имитируют Int, команды Pushf, Popf, Retf 2 делают Iret, но возвращают вызвавшей программе флаги, которые вернул старый обработчик.
Приемы "красивого встраивания" с заменой части команды:
Start: JMP install interupt: pushf ; Предобработка db 9Ah ; call far ;db 0EAh ; JMP FAR int9_sav dd 0 ; два слова pushf ; --¬ ; Постобработка ; ¦ для JMP FAR ненужно, т.к. popf ; ¦ сюда управление не передается retf 2 ; --- Install: ;;;;;;;;;;;;;;;; push cs pop ds mov ax,3509h ; дать адрес старого обработчика int 21h ; прерывания mov word ptr [int9_sav],bx mov word ptr [int9_sav+2],es lea dx,int9 ; или mov dx, offset int9 mov ah,25h ; установить обработчик прерывания int 21h ; al уже установлен
© Колесников Дмитрий Геннадьевич
Учебник по СайтоСтроению
-
Как сэкономить топливо |