7.4.3.8. Коды ошибок
Когда процессор обнаруживает исключение, связанное с
конкретным сегментом, то он запоминает соответствующий код ошибки в стеке программы обработки. Формат кода ошибки подобен
формату селектора, за исключением того, что он имеет два однобитовых поля вместо трехбитового поля
RPL. Формат кода ошибки показан на рис. 3.4.
Код ошибки имеет следующие поля:
Индекс селектора - указывает место в таблицах обработки
ошибок.
Индикатор таблицы TJ-бит 2. Если бит 1 очищен и TI = 0, то
этот бит показывает,
что код ошибки ссылается на таблицу GDT. Если же бит 1 очищен и TI = 1, то
код ошибки ссылается на таблицу LDT.
Бит прерывания 1-бит 1. Процессор устанавливает этот
бит, если индексная часть
кода ошибки ссылается на дескриптор вентиля в таблице IDT.
Бит внешнего события ЕХТ-бит 0. Процессор устанавливает этот
бит, если данное исключение
было вызвано событием, внешним по отношению к текущей программе.
Микропроцессор 80386 распознает шестнадцать определенных
кодов ошибок.
Прерывание 0-ошибка деления на нуль. Эта ошибка возникает во время исполнения команды беззнакового
(DIV) или знакового (IDIV) деления в том случае, если делитель равен нулю.
Прерывание 1-исключения для отладки. Процессор генерирует это общее
прерывание для пяти условий:

Рис. 3.4. Формат кода
ошибки.
ловушка точки останова при переключении задачи;
отказ общего типа;
ловушка точки останова по адресу данных;
отказ точки останова по адресу команды;
ловушка пошагового (покомандного) исполнения.
Будет ли это исключение ловушкой или отказом, зависит от
условия. Процессор не
запоминает в стеке кода ошибки для этого исключения. Напишите собственную программу обработки, которая проверяет регистры
отладки DRO-DR7 для определения
конкретного условия, вызвавшего данное исключение.
Прерывание 3-точка останова. Эта ловушка вызывается командой INT 3 (вызов процедуры прерывания). Команда INT 3 имеет
длину в один байт, что позволяет легко заменять код- операции в исполняемом сегменте на код
операции точки
останова. Запоминаемое в стеке содержимое регистров CS и EIP указывает на байт, следующий за точкой
останова.
Прерывание 4-переполнение. Это прерывание запускается в том
случае, если процессор
выполняет команду INTO (вызов процедуры прерывания по переполнению) и при этом флаг
переполнения установлен. Как знаковая, так и беззнаковая арифметика используют одни и те
же команды. Процессор не может определить, какая из них имелась в виду в
конкретной ситуации. Поэтому он не вызывает исключения по прерыванию автоматически. Он
устанавливает флаг в случае выхода результата из диапазона чисел со знаком.
Прерывание 5-нарушение границы. Этот отказ возникает при
исполнении команды
BOUND (проверка индекса массива на соответствие границе), если операнд оказывается больше, чем значение
границы. Программа может также использовать команду BOUND для проверки индекса массива со
знаком на выход за границы со знаком, которые определены в блоке памяти.
Прерывание 6-неразрешенный код операции. Этот отказ возникает, если в исполнительный блок поступает
неразрешенный код операции. Он не обнаруживается до тех пор, пока процессор не попытается
исполнить команду с таким кодом операции.
Иными словами, предварительная выборка такого кода не вызывает данного
исключения. В стеке код ошибки также не запоминается.
Это исключение может вызвать и другая операция. Отказ
возникает, если тип операнда не соответствует данному коду операции. Например,
прерывание возникает, если команда LES (загрузить полный указатель в
регистр ES) использует в качестве операнда-источника регистр.
Прерывание 7 - сопроцессор отсутствует. Это исключение возникает в одной
из двух ситуаций:
1) процессор обнаруживает либо
команду WAIT, либо команду ESC (сигнал, что
это команда сопроцессора), и оба бита МР и TS в регистре CRO
установлены;
2) процессор обнаруживает команду ESC, и бит
ЕМ регистра CRO установлен.
Прерывание 8 - двойной отказ. Обычно МП 80386 обрабатывает
исключения
последовательно.
Если он не может этого сделать, то возникает двойной отказ. Для того чтобы определить, является
ли данная ошибка условием двойного отказа, процессор разделяет исключения на три класса:
незначительные исключения, сопутствующие исключения и отказы страниц. Код ошибки всегда
запоминается в стеке программы
обработки двойного отказа. Этот код всегда равен нулю. Рестарт с вызвавшей отказ команды невозможен.
Если во время попытки процессора обработать двойной отказ возникает другое исключение, то
процессор прекращает работу.
Три класса двойных отказов показаны на рис. 3.5.
Прерывание 9-выход сопроцессора из сегмента. Это исключение возникает, если процессор в защищенном режиме
обнаруживает нарушение страницы или сегмента при передаче средней части операнда процессора в NPX.
Прерывание 10 - неразрешенный сегмент состояния задачи. Это исключение вызывает попытка переключиться на неразрешенный
сегмент состояния задачи (TSS).
Сегмент TSS может считаться неразрешенным при двенадцати условиях, показанных на рис. 3.6. Код
ошибки заносится в стек и помогает определить условие, вызвавшее исключение. Бит ЕХТ показывает,
было ли это исключение

Рис. 3.5. Три класса
двойных отказов.

Рис. 3.6. Условия
неразрешенного сегмента TSS.
вызвано внешним по отношению к программе условием, таким
как внешнее прерывание
через вентиль задачи, который осуществил переключение на неразрешенный сегмент TSS. Для
того чтобы обеспечить правильный сегмент TSS для обработки этого условия, программа обработки
исключения должна вызываться через вентиль
задачи.
Прерывание 11-сегмент отсутствует. Это исключение появляется, когда МП 80386 обнаруживает, что- бит Р
дескриптора очищен, после этого отказа возможен рестарт. Программа обработки исключения
делает сегмент присутствующим и осуществляет возврат. Затем возобновляется выполнение прерванной
программы. Обычно
операционная система использует это исключение для реализации виртуальной памяти на уровне сегментов.
Прерывание 12-исключение по стеку. Это прерывание появляется при
выполнении одного из двух условий:
когда процессор пытается загрузить регистр SS дескриптором, который помечен как отсутствующий, а в
остальном является допустимым. Такая ситуация может возникнуть во внутреннем уровне вызова или
возврата при переключении задачи, при исполнении команд LSS или MOV и POP со
ссылкой на регистр SS;
при любой операции со ссылкой на регистр SS и
нарушением границы. Эти операции
включают стек - ориентированные команды, такие, как ENTER, LEAVE,POP, PUSH. Сюда
также относятся другие обращения к памяти, предусматривающие использование сегмента SS.
Во всех случаях возможен рестарт с вызвавшей это
прерывание команды, на которую указывает
указатель возврата, запоминаемый в стеке программы обработки этого исключения.
Прерывание 13-исключение общей защиты. Это исключение является «всеядным». Все те нарушения
защиты, которые не вызывают другого исключения, запускают исключение общей защиты. Причины его
следующие:
нарушение
границы сегмента при ссылке на таблицу дескрипторов;
запись в доступный только чтению сегмент данных или в
сегмент программы;
считывание
из доступного только по исполнению сегмента;
загрузка регистров DS, ES, FS, GS или SS дескриптором системного
сегмента;
переключение на занятую задачу;
нарушение правил привилегий;
загрузка регистра CRO битом PG = 1 (включено разбиение на
страницы) и битом РЕ
= 0 (защита не включена);
нарушение границы сегмента при использовании регистров CS, DS, ES, FS,GS;
передача
управления сегменту, который не является исполнительным.
Прерывание 14-отказ страницы. Это прерывание возникает, когда
осуществляется
разбиение на страницы (PG = 1) и процессор обнаруживает при трансляции линейного адреса в физический адрес одно из следующих
условий:
текущая процедура не имеет привилегий, достаточных для
доступа к указанной
странице памяти;
вход в таблицу страниц или в каталог страниц, который нужен
для трансляции адресов, имеет сброшенный
бит присутствия.
Для программы обработки отказа страницы МП 80386 делает
доступными два вида
информации с целью облегчения диагностики ошибки и ее возможной коррекции.
1) Регистр управления CR2. Процессор сохраняет линейный
адрес, использованный при вызвавшем это исключение доступе, в регистре CR2.
Программа обработки
исключения использует этот регистр для локализации соответствующих входов в таблицу страниц и в
каталог страниц.
2) Код ошибки в стеке. Этот код имеет формат,
отличающийся от формата для других исключений. Он сообщает, во-первых, обусловлено ли исключение
отсутствием страницы или же нарушением прав доступа, во-вторых, был ли
вызвавший исключение
доступ к памяти чтением или записью и, в-третьих, находился ли МП 80386 в момент исключения на
уровне пользователя или супервизора.
Прерывание 15 - зарезервировано фирмой Intel
для использования в будущем.

Рис. 3.7. Сводная информация по исключениям.
Прерывание 16 - ошибка сопроцессора. Процессор вызывает это
прерывание, если он обнаруживает сигнал
от арифметического сопроцессора 80287 или 80387 на выводе ERROR #. Процессор проверяет этот
вывод дважды: в начале определенных команд ESC и когда он обнаруживает
команду WAIT при нулевом бите ЕМ в слове состояния машины MSW (т.е. эмуляция сопроцессора не
нужна). На рис. 3.7 приведена
сводная информация об ошибках для каждого из исключений.