Исключение 13 - Общая защита
Исключение общей защиты генерируется для всех нарушений памяти, не вызывающих прочих исключений. Сюда входят (но не ограничивают перечень):
· Превышение границы сегмента при использовании сегментов CS, DS, ES, FS или GS.
· Превышение границы сегмента при ссылке к таблице дескрипторов.
· Передача выполнения сегменту, не являющемуся выполняемым (кодовым) сегментом.
· Попытка записи в сегмент данных, доступный только для чтения, или в кодовый сегмент.
· Чтение из кодового сегмента, доступного только для выполнения.
· Загрузка регистра SS селектором сегмента, доступного только для чтения (если только этот селектор не берется из TSS при переключении задачи, так как в этом случае происходит исключение "неверный TSS").
· Загрузка регистра SS, DS, ES, FS или GS селектором системного сегмента.
· Загрузка регистра DS, ES, FS или GS селектором кодового сегмента, доступного только для выполнения.
· Загрузка регистра SS селектором выполняемого сегмента.
· Доступ к памяти при помощи регистров DS, ES, FS или GS, когда в них содержится пустой селектор.
· Переключение на Занятую задачу.
· Нарушение правил привилегированности.
· Превышение длины команды предельного значения 15 байтов (это может случиться только при использовании перед командой избыточных префиксов).
· Загрузка регистра CR0 при установленном бите PG (подкачка страниц разрешена) и очищенном бите PE (защита запрещена).
· Прерывание или исключение через шлюз прерывания или ловушки из виртуального режима 8086 к обработчику с уровнем привилегированности иному, нежели 0.
Исключение общей защиты по типу относится к сбою. В ответ на исключение общей защиты процессор помещает в стек обработчика исключений код ошибки. Если исключение вызвано загрузкой дескриптора, то код ошибки содержит селектор для данного дескриптора; в противном случае код ошибки является пустым. Источник для селектора в коде ошибки может представлять собой одно из:
1. Операнд команды.
2. Селектор из шлюза, являющегося операндом команды.
3. Селектор из TSS, участвующего в переключении задачи.
Исключение 14 - Страничный сбой
Страничный сбой происходит, когда подкачка страниц разрешена (бит PG регистра CR0 установлен) и процессор обнаруживает одно из следующих условий во время трансляции линейного адреса в физический:
· Элемент каталога страниц или таблицы страниц, необходимый для трансляции адреса, имеет очищенный бит Присутствия, что означает, что таблица страниц или страница, содержащая операнд, не присутствует в физической памяти;
· Процедура не имеет достаточного уровня привилегированности для доступа к указанной странице.
Процессор обеспечивает для обработчика страничного сбоя два информационных элемента, помогающих диагностировать исключение и восстановить нормальные условия:
· Код ошибки в стеке. Код ошибки для страничного сбоя имеет формат, отличный от формата для других особых ситуаций (см. выше). Код ошибки сообщает обработчику исключения следующие три вещи:
1. Произошло ли данное исключение вследствие того, что страница не присутствует, или из-за нарушения прав доступа к странице.
2. Работал ли процессор в момент исключения в режиме пользователя, или в режиме супервизора.
3. Состоял ли доступ к памяти, вызвавший данное исключения, в чтении или в записи.
· Содержимое регистра CR2. Процессор загружает в регистр CR2 32 - разрядный линейный адрес, сгенерировавший исключение. Обработчик исключения может использовать данный адрес для нахождения соответствующих элементов каталога страниц и таблицы страниц. Если во время выполнения обработчика страничного сбоя произойдет еще один страничный сбой, то обработчик должен поместить содержимое регистра CR2 в стек.
Страничный сбой при переключении задачи
Следующие операции выполняют доступ к памяти при переключении задачи:
1. Запись состояния исходной задачи в TSS для этой задачи.
2. Чтение GDT для нахождения дескриптора TSS новой задачи.
3. Чтение TSS новой задачи для проверки типов дескрипторов сегмента из TSS.
4. Может быть выполнено чтение LDT новой задачи для верификации сегментных регистров, хранимых в новом TSS.
Страничный сбой может являться результатом обращения к одной из этих операций. В двух последних случаях исключение происходит в контексте новой задачи. Указатель команд указывает на следующую команду новой задачи, а не на команду вызвавшую переключение задачи (или на последнюю выполняемую команду в случае прерывания). Если устройство операционной системы позволяет страничным сбоям происходить вовремя переключения задач, то обработчик страничного сбоя должен вызываться через шлюз задачи.
Страничный сбой при противоречивом значении указателя стека
Следует обращать особое внимание на то, чтобы страничный сбой не приводил к использованию процессором неверного указателя стека (SS:ESP). Программное обеспечение, написанное для 16-битовых процессоров Intel, часто использует для переключения на новый стек пару команд, например,
MOV SS, AX
MOV SP, StackTop
В случае процессора i486+, поскольку вторая команда обращается к памяти, можно получить в данном случае страничный сбой после того, как был изменен селектор сегментного регистра SS, но перед тем, как соответственно было изменено содержимое регистра SP. В этой точке две части указателя стека SS:SP (разумеется, для 32-разрядных программ это SS:ESP) противоречивы друг с другом. Новый стековый сегмент используется со старым указателем стека.
Процессор не использует противоречащий указатель стека, если обработка страничного сбоя вызывает переключение стека на хорошо определенный стек (т.е. обработчик это задача или более привилегированная процедура). Однако, если страничный сбой происходит на том же уровне привилегированности и в той же задаче, что и для обработчика страничного сбоя, то процессор попытается использовать стек, на который указывает противоречивый указатель стека.
В системах, использующих подкачку страниц и обрабатывающих страничные сбои в пределах задач, содержащих сбой (посредством шлюзов ловушки или прерывания), программное обеспечение, выполняемое на том же уровне привилегированности, что и обработчик страничного сбоя, должно инициализировать новый стек командой LSS, а не парой команд, показанной выше. Если обработчик страничного сбоя работает на уровне привилегированности 0 (нормальный случай), проблема ограничивается программами, работающими на уровне привилегированности 0, т.е. обычно ядром операционной системы.