При закрытии подписчики были переданы в рассылку "Для бухгалтера: программы, новости, советы" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Сегодня в номере:
Прерывания и исключения - это такие события, при которых процессор прекращает выполнение текущей программы и выполняет специальную процедуру - обработчик прерывания. При этом состояние процессора, как правило, сохраняется, что дает возможность безболезненно продолжить выполнение прерванной программы, причем для программы возникновение этого события пройдет совершенно незамеченным.
Чем различаются прерывания и исключения? Исключения порождаются процессором, когда при выполнении кода он наталкивается на какую-нибудь ошибку, к примеру деление на ноль. В настоящее время процессоры IA-32 имеют около двух десятков исключений для разных видов ошибок.
Прерывания могут вызываться как внешними устройствами (аппаратные прерывания), так и самой программой (программные прерывания). При этом программные прерывания, в принципе, немногим отличаются от обычного вызова процедуры.
Аппаратные прерывания - способ, с помощью которых внешние (относительно процессора) устройства могут влиять на работу процессора, например сигнализировать ему об окончании выполнения какого-либо действия. Они подразделяются на маскируемые (которые процессор получает на вход INTR) и одно немаскируемое прерывание (NMI - NonMaskable Interrupt) (получаемое уже на другой вход - NMI; другой вариант - получение процессором по системной шине или шине APIC (Advanced Programmable Interrupt Controller) сообщения с режимом доставки NMI). Альтернативный способ получения прерываний - через APIC, но о нем мы поговорим позже. Маскируемые прерывания могут быть отключены снятием флага IF регистра EFLAGS (для этого предназначена инструкция CLI). Для отключения немаскируемого прерывания необходимо перепрограммировать контроллер прерываний
IF
EFLAGS
CLI
При возникновении прерывания, процессору известен только номер прерывания (также называемый вектором). Поскольку сам по себе этот номер ничего не говорит о том, где именно находится процедура-обработчик, эту информацию процессор должен почерпнуть из специальной таблицы - назовем ее таблицей прерываний.
В режиме реальных адресов таблица прерываний находится по абсолютному адресу 0:0 - 0:0x400 и представляет из себя 256 абсолютных (сегмент:смещение) четырехбайтных адресов процедур-обработчиков.Процессору остается только взять из этой таблицы адрес соответствующего номеру прерывания обработчика, и выполнить переход на этот адрес.
В защищенном режиме таблица прерываний называется таблицей дескрипторов прерываний IDT (Interrupt Descriptors Table) и на ее местонахождение указывает регистр IDTR (interrupt descriptors table register). Уже по названию можно судить, что в ней находятся не просто адреса обработчиков, а дескрипторы обработчиков прерывания. В качестве таких дескрипторов могут выступать дескрипторы трех типов:
О шлюзах задачи мы поговорим позже, когда коснемся аппаратной поддержки многозадачности в IA-32, ну а пока выясним чем отличаются шлюзы ловушек и шлюзы прерываний
При вызове обработчика прерывания через шлюз прерывания, дальнейшая их обработка запрещается до завершения обработчика. При вызове через шлюз ловушки этого не происходит. Соответственно, первый метод больше подходит для аппаратных прерываний (т.к. обработчик должен быть уверен, что он монопольно контролирует устройство, во избежание аппаратных сбоев), а второй метод - для программных прерываний (которые должны иметь повторную входимость или реентерабельность)
бит 7 бит 6 бит 5 бит 4 бит 3 бит 2 бит 1 бит 0 +-------+-------+-------+-------+-------+-------+-------+-------+ байт 0 | ------- биты 7-0 смещения процедуры-обработчика --------- | +-------+-------+-------+-------+-------+-------+-------+-------+ +-------+-------+-------+-------+-------+-------+-------+-------+ байт 1 | ------- биты 15-8 смещения процедуры-обработчика --------- | +-------+-------+-------+-------+-------+-------+-------+-------+ +-------+-------+-------+-------+-------+-------+-------+-------+ байт 2 | --- биты 7-0 селектора сегмента процедуры-обработчика ---- | +-------+-------+-------+-------+-------+-------+-------+-------+ +-------+-------+-------+-------+-------+-------+-------+-------+ байт 3 | --- биты 15-8 селектора сегмента процедуры-обработчика ---- | +-------+-------+-------+-------+-------+-------+-------+-------+ +-------+-------+-------+-------+-------+-------+-------+-------+ байт 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +-------+-------+-------+-------+-------+-------+-------+-------+ +-------+-------+-------+-------+-------+-------+-------+-------+ байт 5 | P | DPL | 0 | ------- Тип шлюза --------- | +-------+-------+-------+-------+-------+-------+-------+-------+ Поля P и DPL имеют такое же значение, как и в дескрипторе сегмента, Поле "тип шлюза" принимает одно из следующих значений: 0110 - 16-битный шлюз прерывания 0111 - 16-битный шлюз ловушки 1110 - 32-битный шлюз прерывания 1111 - 32-битный шлюз ловушки +-------+-------+-------+-------+-------+-------+-------+-------+ байт 6 | ------- биты 23-16 смещения процедуры-обработчика --------- | +-------+-------+-------+-------+-------+-------+-------+-------+ +-------+-------+-------+-------+-------+-------+-------+-------+ байт 7 | ------- биты 31-24 смещения процедуры-обработчика --------- | +-------+-------+-------+-------+-------+-------+-------+-------+
При вызове обработчика прерывания процессор сохраняет в стеке значения регистров EFLAGS, CS и EIP. Возврат из обработчика осуществляется командой IRETD, которая восстанавливает значения, сохраненные в стеке. Поподробнее об исключениях Исключения в процессорах IA-32 бывают трех видов: fault (сбой), trap (ловушка) и abort (останов). Тип исключения зависит от того, когда процессор заметил ошибку, приведшую к исключению, и, следовательно, - куда указывают сохраненные в стеке CS:EIP, что в свою очередь определяет, возможно ли продолжение программы после завершения прерывания. Как правило, это выглядит так: abort - надежное восстановление выполнения программы невозможно, CS:EIP или EFLAGS могут иметь ошибочные значения fault - CS:EIP указывает на ту инструкцию, из-за которой произошло исключение. После исправления ситуации возможно дальнейшее выполнене программы trap - CS:EIP указывает на следующую после "пойманной" инструкцию. После завершения обработчика, программа может спокойно продолжать выполняться (как и при программных прерываниях). Все исключения IA-32 мы рассмотрим в следующем выпуске Outro На сегодня все, уважаемые подписчикиКак всегда, мой почтовый ящик открыт для вас: lonesome@lowlevel.ru Также вы можете задавать интересующие вас вопросы в форуме lowlevel.ru Предыдущие выпуски рассылки вы можете найти по этому адресу: http://subscribe.ru/archive/comp.soft.prog.osdev Всего наилучшего! Lonesome http://subscribe.ru/ E-mail: ask@subscribe.ru Отписаться Убрать рекламу
IRETD
Исключения в процессорах IA-32 бывают трех видов: fault (сбой), trap (ловушка) и abort (останов). Тип исключения зависит от того, когда процессор заметил ошибку, приведшую к исключению, и, следовательно, - куда указывают сохраненные в стеке CS:EIP, что в свою очередь определяет, возможно ли продолжение программы после завершения прерывания. Как правило, это выглядит так:
Все исключения IA-32 мы рассмотрим в следующем выпуске
На сегодня все, уважаемые подписчикиКак всегда, мой почтовый ящик открыт для вас: lonesome@lowlevel.ru Также вы можете задавать интересующие вас вопросы в форуме lowlevel.ru Предыдущие выпуски рассылки вы можете найти по этому адресу: http://subscribe.ru/archive/comp.soft.prog.osdev Всего наилучшего! Lonesome
{#template MAIN} {#include js_tmpl_auth_reg_tab} {#if $P.login_register_tab == 1} Войти на сайт {* {#include js_tmpl_auth_reg_button} *} {#include js_tmpl_auth_reg_action} {#include js_tmpl_auth_reg_descr} Если вы еще не с нами, то начните с регистрации Вход для авторов {#/if} {#if $P.login_register_tab == 2} Регистрация {* {#include js_tmpl_soc_auth_reg_descr} *} {#include js_tmpl_auth_reg_soc} {#include js_tmpl_auth_reg_agree} {* #include js_tmpl_auth_reg_descr *} {#include js_tmpl_auth_reg_action} {* {#include js_tmpl_auth_reg_button} *} {#include js_tmpl_auth_reg_descr} {#include js_tmpl_soc_auth_reg_descr} {#/if} {* *} {#/template MAIN} {#template js_tmpl_auth_reg_tab} Вход на сайт Регистрация {#/template js_tmpl_auth_reg_tab} {#template js_tmpl_auth_reg_action} {#if $P.login_register_tab == 1} {#include js_tmpl_auth_reg_soc} {#/if} {#if $P.login_register_tab == 1} E-mail или код подписчика Пароль Русская раскладка клавиатуры! У вас включен Caps Lock! У вас включен Caps Lock и русская раскладка клавиатуры! Чужой компьютер Забыли пароль? {#/if} {#if $P.login_register_tab == 2} E-mail Я ознакомился и согласен с условиями сервиса Subscribe.ru Нажимая на кнопку "Готово!", я даю согласие на обработку персональных данных {* Я хочу получать новости о скидках на одежду *} Готово! {#/if} {#/template js_tmpl_auth_reg_action} {#template js_tmpl_auth_reg_agree} Я ознакомился и согласен с условиями сервиса Subscribe.ru {#/template js_tmpl_auth_reg_agree} {#template js_tmpl_auth_reg_button} {#if $P.login_register_tab == 1} Email OpenID Вконтакте Mail.Ru {#/if} {#if $P.login_register_tab == 2} Email OpenID Вконтакте Mail.Ru {#/if} {#/template js_tmpl_auth_reg_button} {#template js_tmpl_auth_reg_descr} {#if $P.login_register_tab == 1} Для оформления подписки на выбранную рассылку, работы с интересующей вас группой или доступа в нужный вам раздел, просим авторизоваться на Subscribe.ru {#/if} {#if $P.login_register_tab == 2} Для регистрации укажите ваш e-mail адрес. Адрес должен быть действующим, на него сразу после регистрации будет отправлено письмо с инструкциями и кодом подтверждения. {#/if} {#/template js_tmpl_auth_reg_descr} {#template js_tmpl_soc_auth_reg_descr} Или зарегистрируйтесь через социальную сеть. {#/template js_tmpl_soc_auth_reg_descr} {#template js_tmpl_auth_reg_soc} {#if $P.login_register_tab == 1} {#/if} {#if $P.login_register_tab == 2} {#/if} {#/template js_tmpl_auth_reg_soc}
{#include js_tmpl_auth_reg_descr}
{#template MAIN} {#include js_tmpl_auth_reg_tab} {#include js_tmpl_auth_reg_descr} {#include js_tmpl_auth_reg_action} {#/template MAIN} {#template js_tmpl_auth_reg_tab} Регистрация {#/template js_tmpl_auth_reg_tab} {#template js_tmpl_auth_reg_descr} Пожалуйста, подтвердите ваш адрес.Вам отправлено письмо для подтверждения вашего адреса {$P.register_confirm_mail}.Для подтверждения адреса перейдите по ссылке из этого письма. {#/template js_tmpl_auth_reg_descr} {#template js_tmpl_auth_reg_action} Или введите код из письма: Не пришло письмо? Пожалуйста, проверьте папку Спам (папку для нежелательной почты). Вышлите мне письмо еще раз! Готово {#/template js_tmpl_auth_reg_action}