Механизм работы прерываний. Понятие вектора прерываний. Системные и пользовательские прерывания. Их назначения. Способы обработки прерываний. 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Механизм работы прерываний. Понятие вектора прерываний. Системные и пользовательские прерывания. Их назначения. Способы обработки прерываний.



Прерывания обычно вызываются внешними устройствами. Прерывание сигнализирует процесору о необходимости прервать текущие действия и ответить внешнему устройству. В IBM PC клавиатура посылает сигнал прерывания всякий раз при нажатии любой клавиши. Прерывание клавиатуры заставляет процессор прекратить текущую деятельность и считать набранный на клавиатуре символ.

Легко понять, за что прерывания получили свое название. Прерывание сигнализирует о необходимости "прервать" текущее действие процессора. Прерывания хороши тем, что избавляют процессор постоянного контроля за внешними устройствами. Работа 8088 с прерываниями во многом напоминает его обращение с процедурами. Прерывание не может прекратить работу процессора во время выполнения команды. Сначала 8088 закончит выполнение текущей команды, но следующую уже проигнорирует. Вместо ее выполнения процессор действует так, как будто следующая команда была вызовом проедуры. Он сохраняет адрес очередной команды в стеке и переходит в специальную процедуру, которую называют программой обработки прерываний. Эта процедура содержит команды для работы с вызвавшим прерывание устройством. В случае с клавиатурой программа обработки прерывания считывает символ и сохраняет его для дальнейшего использования. После того как она закончит работу с устройством, происходит возврат в точку прерывания. Процессор извлекает из стека адрес возврата и продолжает выполнение программы как будто ничего не случилось. Поскольку прерывание вызывается внешним устройством, оно может произойти в любой момент выполнения программы. Программа не может предпринять каких-либо действий чтобы подготовиться к прерыванию, так как не может предвидеть, когда пользователь нажмет на клавишу клавиатуры. Отсюда следует, что прерывание не должно изменять данные в прерываемой программе.

Вектор прерываний

Еще одна важная составная часть микропроцессора 8088 - механизм прерываний. Эта компонента системы встроена в микропроцессор, и обеспечивает эффективные методы обработки прерываний. Когда микропроцессор 8088 получает сигнал о необходимости прерывания, он определяет, какое из усройств требует обслуживания посредством аппаратной процедуры, известной как цикл подтверждения прерывания. В IBM PC для обслуживания внешних прерываний используется контроллер прерываний 8259 фирмы Intel. Контроллер прерываний программируется так, чтобы выдавать однобайтовое число в ответ на цикл подтверждения прерывания микропроцессора 8088. Это число, находящееся в диапазоне от 0 до 255, - номер прерывания внешнего усройства, вызвавшего прерывание. В персональной ЭВМ контроллер прерываний обслуживает восемь внешних прерываний, которым соответствуют номера от 8 до 15.

Как только микропроцессор 8088 получает номер прерывания, он должен передать управление соответствующей программе обработки прерывания. Первые 1024 байт памяти микропроцессора 8088

зарезервированы для векторов прерываний. Каждому из 256 возможных прерываний отводится четырехбайтовая область. Прерывание 0 имеет четыре байта по адресам от 0 до 3, прерывание 1 - от 4 до 7, и т.д.

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

Когда возникает прерывание, микропроцессор помещает в стек региср флагов, за которым следуют регистры CS и IP. 8088 использует номер прерывания, чтобы считать указатель на программу обработки

прерывания, и передать ей управление. Теперь уже эта программа отвечает за сохранение регистров, которые она использует, и восстановление их перед возвратом управления в прерванную процедуру. Для возврата из прерывания используется специальная команда IRET. Она извлекает верхние три слова из стека и помещает их в регистры IP, CS и регистр флагов.

Аппаратные прерывания

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

прерывания в качестве указателя подпрограммы обработки прерывания.

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

Обработчики прерываний

Когда в реальном режиме выполняется команда INT, управление передается по адресу, который считывается из специального массива, таблицы векторов прерываний, начинающегося в памяти по адресу 0000h:0000h. Каждый элемент этого массива представляет собой дальний адрес обработчика прерывания в формате сегмент:смещение или 4 нулевых байта, если обработчик не установлен. Команда INT помещает в стек регистр флагов и дальний адрес возврата, поэтому, чтобы завершить обработчик, надо выполнить команды popf и retf или одну команду iret, которая в реальном режиме полностью им аналогична.

; Пример обработчика программного прерыванияint_handler proc far mov ax,0 iretint_handler endp

После того как обработчик написан, следующий шаг — привязка его к выбранному номеру прерывания. Это можно сделать, прямо записав его адрес в таблицу векторов прерываний, например так:

push 0; сегментный адрес таблицы; векторов прерываний pop es; в ES pushf; поместить регистр флагов в стек cli; запретить прерывания; (чтобы не произошло аппаратного прерывания между следующими; командами, обработчик которого теоретически может вызвать INT 87h; в тот момент, когда смещение уже будет записано, а сегментный; адрес еще нет, что приведет к передаче управления; в неопределенную область памяти); поместить дальний адрес обработчика int_handler в таблицу; векторов прерываний, в элемент номер 87h (одно из неиспользуемых прерываний) mov word ptr es:[87h*4], offset int_handler mov word ptr es:[87h*4+2], seg int_handler popf; восстановить исходное значение флага IF

Теперь команда INT 87h будет вызывать наш обработчик, то есть приводить к записи 0 в регистр АХ.

Перед завершением работы программа должна восстанавливать все старые обработчики прерываний, даже если это были неиспользуемые прерывания типа 87h — автор какой-нибудь другой программы мог подумать точно так же.

Хотя прямое изменение таблицы векторов прерываний и кажется достаточно удобным, все-таки это не лучший подход к установке обработчика прерывания, и пользоваться им следует только в случаях крайней необходимости, например внутри обработчиков прерываний. Для обычных программ DOS предоставляет две системные функции: 25h и 35h — установить и считать адрес обработчика прерывания, которые и рекомендуются к использованию в обычных условиях:

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

Разумеется, вызов исключения при ошибке занимает много времени, но, если массив достаточно большой и неупорядоченный, значительная часть проверок будет происходить без ошибок и быстро.

При помощи собственных обработчиков исключений можно справиться и с другими особыми ситуациями, например обрабатывать деление на ноль и остальные исключения, которые могут происходить в программе. В реальном режиме можно столкнуться всего с шестью исключениями:

#DE (деление на ноль) — INT 0 — ошибка, возникающая при переполнении и делении на ноль. Как для любой ошибки, адрес возврата указывает на ошибочную команду.

#DB (прерывание трассировки) — INT 1 — ловушка, возникающая после выполнения каждой команды, если флаг TF установлен в 1. Используется отладчиками, действующими в реальном режиме.

#OF (переполнение) — INT 4 — ловушка, возникающая после выполнения команды INTO, если флаг OF установлен.

#ВС (переполнение при BOUND) — INT 5 — уже рассмотренная нами ошибка, возникающая при выполнении команды BOUND.

#UD (недопустимая команда) — INT 6 — ошибка, возникающая при попытке выполнить команду, отсутствующую на данном процессоре.

#NM (сопроцессор отсутствует) — INT 7 — ошибка, возникающая при попытке выполнить команду FPU, если FPU отсутствует.

Прерывания от внешних устройств, или аппаратные прерывания — это то, что понимается под термином «прерывание». Внешние устройства (клавиатура, дисковод, таймер, звуковая карта и т.д.) подают сигнал, по которому процессор прерывает выполнение программы и передает управление на обработчик прерывания. Всего на персональных компьютерах используется 15 аппаратных прерываний, хотя теоретически возможности архитектуры позволяют довести их число до 64.

Рассмотрим их кратко в порядке убывания приоритетов (прерывание имеет более высокий приоритет, и это означает, что, пока не завершился его обработчик, прерывания с низкими приоритетами будут ждать своей очереди).

IRQ0 (INT 8) — прерывание системного таймера. Это прерывание вызывается 18,2 раза в секунду. Стандартный обработчик этого прерывания вызывает INT 1Ch при каждом вызове, так что, если программе необходимо только регулярно получать управление, а не перепрограммировать таймер, рекомендуется использовать прерывание 1Ch.

IRQ1 (INT 9) — прерывание клавиатуры. Это прерывание вызывается при каждом нажатии и отпускании клавиши на клавиатуре. Стандартный обработчик этого прерывания выполняет довольно много функций, начиная с перезагрузки по Ctrl-Alt-Del и заканчивая помещением кода клавиши в буфер клавиатуры BIOS.

IRQ2 — к этому входу на первом контроллере прерываний подключены аппаратные прерывания IRQ8 – IRQ15, но многие BIOS перенаправляют IRQ9 на INT 0Ah.

IRQ8 (INT 70h) — прерывание часов реального времени. Это прерывание вызывается часами реального времени при срабатывании будильника и если они установлены на генерацию периодического прерывания (в последнем случае IRQ8 вызывается 1024 раза в секунду).

IRQ9 (INT 0Ah или INT 71h) — прерывание обратного хода луча. Вызывается некоторыми видеоадаптерами при обратном ходе луча. Часто используется дополнительными устройствами (например, звуковыми картами, SCSI-адаптерами и т.д.).

IRQ10 (INT 72h) — используется дополнительными устройствами.

IRQ11 (INT 73h) — используется дополнительными устройствами.

IRQ12 (INT 74h) — мышь на системах PS используется дополнительными устройствами.

IRQ13 (INT 02h или INT 75h) — ошибка математического сопроцессора. По умолчанию это прерывание отключено как на FPU, так и на контроллере прерываний.

IRQ14 (INT 76h) — прерывание первого IDE-контроллера «операция завершена».

IRQ15 (INT 77h) — прерывание второго IDE-контроллера «операция завершена».

IRQ3 (INT 0Bh) — прерывание последовательного порта COM2 вызывается, если порт COM2 получил данные.

IRQ4 (INT 0Ch) — прерывание последовательного порта СОМ1 вызывается, если порт СОМ1 получил данные.

IRQ5 (INT 0Dh) — прерывание LPT2 используется дополнительными устройствами.

IRQ6 (INT 0Eh) — прерывание дисковода «операция завершена».

IRQ7 (INT 0Fh) — прерывание LPT1 используется дополнительными устройствами.

Самые полезные для программ аппаратные прерывания — прерывания системного таймера и клавиатуры. Так как их стандартные обработчики выполняют множество функций, от которых зависит работа системы, их нельзя заменять полностью, как мы делали это с обработчиком INT 5. Следует обязательно вызвать предыдущий обработчик, передав ему управление следующим образом (если его адрес сохранен в переменной old_handler, как в предыдущих примерах):

pushf call old_handler

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

jmp cs:old_handler

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

 



Поделиться:


Последнее изменение этой страницы: 2017-02-06; просмотров: 658; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.212.87.137 (0.119 с.)