Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SP_MET_2.DOC
Скачиваний:
13
Добавлен:
02.05.2019
Размер:
689.66 Кб
Скачать
      1. Взаимодействие прикладных и системных обработчиков прерываний

Самыми полезными для программ аппаратными прерываниями являются, пожалуй, прерыва­ния системного таймера и клавиатуры. Так как их стандартные обработ­чики выполняют множество функций, от которых зависит работа сис­темы, их нельзя заменять полностью. Следует обязательно вызвать предыдущий обработчик, передав ему управление либо до, либо после выполнения необходимых действий. Эта методика называется сцеплением прикладного и системного обработчиков прерывания.

Если прикладной обработчик выполняет свои основные действия после системного обработчика, то вначале он должен вызвать системный обработчик следующим образом (если его адрес сохранен в перемен­ной old_handler, как в предыдущих примерах):

pushf

call old_handler

Эти две команды выполняют действие, аналогичное команде INT (со­хранить флаги в стеке и передать управление подобно команде call), так что, когда обработчик завершится командой IRET, управление вернется в прерванную программу.

Другой способ — простая команда JMP — применяется, если прикладной обработчик вызывает системный после выполнения своих действий:

jmp cs:old_handler

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

Механизм аппаратных прерываний позволяет процессору выполнять одну программу, в то время как отдельные программы следят за временем, считывают символы из клавиатуры и по­мещают их в буфер, получают и передают данные через последователь­ные и параллельные порты и даже обеспечивают многозадачность, переключая процессор между разными задачами по прерыванию сис­темного таймера.

Разумеется, обработка прерываний не должна занимать много време­ни: если прерывание происходит достаточно часто (например, прерыва­ние последовательного порта может происходить 28 800 раз в секунду), его обработчик обязательно должен выполняться за более короткое время. Если, например, обработчик прерывания таймера будет выпол­няться 1/32,4 секунды, то есть половину времени между прерываниями, вся система будет работать в два раза медленнее. А если еще одна программа с таким же долгим обработчиком перехватит это прерывание, си­стема остановится совсем. Именно поэтому обработчики прерываний обычно пишут на ассемблере.

Обработчики прерываний могут разрабатываться с учетом того, что возможно возникновение обрабатываемого им прерывания в то время, пока не закончилась обработка предыдущего, то есть прерывание обработчика и повторный вход в него же. Если такая ситуация правильно обрабатывается и не приводит к сбою, обработчик называется повторно входимым (реентерабельным). Некоторые критические участки кода может понадобиться защитить от прерываний, временно их запретив командой CLI (сброс флага прерываний). Следует, однако, помнить, что пока прерывания запрещены, система не отсле­живает изменения часов, не получает данных с клавиатуры. Поэтому прерывания надо обязательно, при первой возможности, разрешать (командой STI).

К сожалению, в MS-DOS самый важный обработчик прерываний в системе — обработчик INT 21h — не является повторно входимым. В от­личие от прерываний BIOS, обработчики которых используют стек пре­рванной программы, обработчик системных функций DOS записывает в SS:SP адрес дна одного из трех внутренних стеков DOS. Если функ­ция была прервана аппаратным прерыванием, обработчик которого вызвал другую функцию DOS, она будет пользоваться тем же стеком, затирая все, что туда поместила прерванная функция. Когда управление вернется в прерванную функцию, в стеке окажется мусор и произойдет ошибка. Лучший выход — вообще не использовать прерывания DOS из обработчиков аппаратных прерываний, но если это действительно нуж­но, то принять необходимые меры предосторожности. Если прерывание произошло в тот момент, когда не выполнялось никаких системных функций DOS, ими можно безбоязненно пользоваться. Чтобы опреде­лить, занята DOS или нет, надо сначала, до установки собственных об­работчиков, определить адрес флага занятости DOS:

Функция DOS 34h — Определить адрес флага занятости DOS

Ввод: АН = 34h

Вывод: ES:BX = адрес однобайтного флага занятости DOS

ES:BX ­– 1 = адрес однобайтного флага критической ошибки DOS

Теперь обработчик прерывания может проверять состояние этих фла­гов и, если оба флага равны нулю, разрешается свободно пользоваться функциями DOS.

Если флаг критической ошибки не ноль, никакими функциями DOS пользоваться нельзя. Если не равен нулю только флаг занятости DOS, можно пользо­ваться только функциями 01h — 0Ch, а чтобы воспользоваться какой-ни­будь другой функцией, придется отложить действия до тех пор, пока DOS не освободится. Чтобы это сделать, надо сохранить номер функции и параметры в каких-нибудь переменных в памяти и установить обра­ботчик прерывания 8h или 1Ch. Этот обработчик должен будет при каждом вы­зове проверять флаги занятости и, если DOS освободилась, вызовет функцию с номером и параметрами, оставленными в переменных в па­мяти. Кроме того, участок программы после проверки флага занятости — критический, и прерывания должны быть запрещены.

Не все функции DOS, однако, быстро возвращают управление — функция чте­ния символа с клавиатуры может оставаться в таком состоянии довольно длительное время, пока пользователь не нажмет на ка­кую-нибудь клавишу, и все это время флаг занятости DOS будет уста­новлен в 1. В DOS предусмотрена и такая ситуация. Все функции ввода символов с ожиданием вызывают INT 28h в том же цикле, в котором они опрашивают клавиатуру, так что, если установить обработчик прерыва­ния 28h, из него можно вызывать все функции DOS, кроме 01 — 0Ch.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]