8.6 Организация обработки прерываний в программах на ассемблере
8. 6 Организация обработки прерываний в программах на ассемблере Организация обработки программных прерываний сводится к написанию обработчика прерывания и установке вектора прерывания для требуемого номера прерывания. Написание обработчика прерывания включает написание специальным образом оформленной процедуры, заканчивающейся командой IRET, и, если это обработчик аппаратных прерываний, необходимо в конце процедуры обработки прерывания разблокировать контроллер прерываний посылкой ему сигнала конца прерывания EOI. Для установки вектора прерывания требуется вычислить смещение от начала таблицы векторов прерываний и записать по этому смещению сегмент обработчика прерывания и его смещение. Далее будут более подробно рассмотрены все необходимые действия по организации обработки прерывания.
8. 7 Написание процедуры обработки программных прерываний Любая процедура обработки прерываний должна заканчиваться командой возврата из процедуры обработки прерывания IRET. Поскольку при возникновении прерывания выполнение текущей программы прерывается, при входе в процедуру обработки прерывания все регистры, кроме CS, IP и регистра флагов содержат те значения, которые были в них до возникновения прерывания. Чтобы прерванная программа могла работать корректно после завершения процедуры обработки прерывания, необходимо в начале процедуры обработки прерывания сохранить все используемые в ней регистры, а в конце, перед командой IRET, восстановить их значения. Значения регистров обычно сохраняются в стеке. Поскольку процедура обработки прерываний работает с тем стеком, который был у прерванной программы и его размер неизвестен, процедура обработки прерываний не должна записывать в стек большой объем данных и должна восстановить его первоначальное состояние к своему завершению. Сохранять значение регистров SS и SP в этом случае не требуется. Другой немаловажной проблемой является доступ программы к своим данным. Так как регистры DS и ES содержат значения сегментов, относящихся к прерванной программе, для доступа к данным можно либо использовать префикс замены сегмента “CS: ” (если данные расположены в том же сегменте, где и команды), либо настроить регистр DS или ES на необходимый сегмент данных. В следующем примере показан общий вид процедуры обработки программных прерываний, сохраняющей значения всех регистров (кроме SS, SP, и CS) и настраивающей регистр DS на сегмент данных.
Data SEGMENT A DB 0 B DW 1 C DD 2 Data ENDS
Code SEGMENT MyProc PROC ; процедура обработки прерывания PUSH AX ; сохранение регистров PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH BP PUSH DS PUSH ES MOV AX, Data MOV DS, AX; настройка DS на сегмент Data MOV ES, AX; настройка ES на сегмент Data POP ES ; восстановление регистров POP DS POP BP POP DI POP SI POP DX POP CX POP BX POP AX IRET ; возврат из процедуры MyProc ENDP Code ENDS В этом примере регистры DS и ES настраиваются на сегмент данных Data, содержащий переменные, необходимые процедуре обработки прерывания. Еще одним аспектом написания процедуры обработки прерывания является переключение стека. Это значит, что процедура обработки прерывания будет использовать свой собственный стек. Для этого сначала необходимо сохранить старые значения регистров SS и SP. Но в стеке их сохранить нельзя, так как ставится задача использовать собственный стек, который еще не инициализирован. Значения регистров SS и SP сохраняются в ячейках памяти. Причем эти ячейки памяти должны находиться в сегменте команд, так как перед настройкой регистра DS на сегмент данных, его значение сначала нужно сохранить в стеке, который еще не инициализирован. Для обращения к ячейкам памяти, находящимся в сегменте команд, в этом случае требуется использовать префикс замены сегмента “CS: ”. После сохранения значений регистров SS и SP они инициализируются новыми значениями – регистр SS настраивается на сегмент стека, а в регистр SP заносится размер стека в байтах. Следующий пример демонстрирует переключение стека в процедуре обработки прерывания.
Data SEGMENT A DB 0 B DW 1 C DD 2 Data ENDS
Stac SEGMENT PARA STACK DB 512 DUP (? ) Stac ENDS
Code SEGMENT MyProc PROC ; процедура обработки прерывания MOV CS: OLD_AX, AX; сохранение AX MOV CS: OLD_SS, SS ; сохранение SS MOV CS: OLD_SP, SP ; сохранение SP MOV AX, Stac MOV SS, AX ; переключение стека MOV SP, 512 PUSH BX ; сохранение регистров PUSH CX PUSH DX PUSH SI PUSH DI PUSH BP PUSH DS PUSH ES MOV AX, Data MOV DS, AX; настройка DS на сегмент Data MOV ES, AX; настройка ES на сегмент Data POP ES ; восстановление регистров POP DS POP BP POP DI POP SI POP DX POP CX POP BX MOV AX, CS: OLD_SS MOV SS, AX ; восстановление стека MOV SP, CS: OLD_SP MOV AX, CS: OLD_AX; восстановление AX IRET ; возврат из процедуры OLD_SS DW? OLD_SP DW? OLD_AX DW? MyProc ENDP Code ENDS
В этом примере стек переключается два раза – в начале процедуры он переключается со старого на новый, а в конце программы – обратно на старый. Поскольку для загрузки регистра SS используется регистр AX, его тоже необходимо сохранить в ячейке памяти, а затем восстановить из нее.
Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|