Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПиП МПС(Ассемблер Левицкий экт 4) / MProc / M5 / Прерывания и исключения.doc
Скачиваний:
77
Добавлен:
16.04.2013
Размер:
238.08 Кб
Скачать

Обработка прерываний в защищенном режиме

В защищенном режиме вызов подпрограмм обслуживания прерываний осуществляется через дескрипторную таблицу прерываний IDT(InterruptDescriptorTable), которая может располагаться в любом месте адресного пространства. Базовый линейный адрес этой таблицы хранится в регистреIDTR(рис.??).

Загрузка содержимого регистра IDTRосуществляется с помощью инструкции LIDT,а его сохранение в памяти - с помощью инструкции SIDT. Инструкция LIDTявляется привилегированной и может выполняться только программой, имеющей высший уровень привилегийCPL=0. Инструкция SIDTможет быть выполнена при любом уровне привилегий программы.

Элементами таблицы IDTявляются системные дескрипторы прерываний, имеющие размер по 8 байт. Поэтому максимальный размер таблицы IDT составляет 2 Кбайт при использовании всех 256 видов прерываний (исключений). В таблице могут содержаться три вида системных дескрипторов: шлюз прерывания, шлюз ловушки и шлюз задачи.

Форматы содержимого шлюзов прерывания и ловушки приведены на рис 8.4,а,б. Они содержат селектор вызываемого при обслуживании сегмента, который поступает в регистрCS, и относительный адрес первой инструкции подпрограммы обслуживания, который загружается в регистрEIP. В дескрипторе также содержится битP, указывающий на присутствие (при значенииP=1) в памяти сегмента, в котором находится соответствующая подпрограмма обслуживания, и 2-битовое полеgDPL, определяющее уровень привилегий шлюза (см. раздел 7.1). БитDв байте доступа определяет режим работы процессора при обслуживании прерываний если значениеD=0, то процессор функционирует как 16-разрядный процессор 80286, еслиD=1, то обеспечивается нормальный 32-разрядный режим функционирования.

Передача управления через шлюз прерывания или шлюз ловушки может сопровождаться изменением уровня привилегий. Процессор проверяет значение gDPL в дескрипторе шлюза при выполнении программных прерываний, вызываемых инструкциями INT n, INT3, INTO.Переход к выполнению подпрограммы обслуживания в этих случаях производится, еслиCPLgDPL, т.е. численное значение уровня привилегий текущей программы меньше или равно значению уровня привилегий шлюза. Таким образом, величинаgDPLограничивает уровень привилегий программ, которые могут вызывать процедуру обслуживания программного прерывания. При выполнении других видов прерываний и исключений процессор игнорирует gDPL шлюза.

Привилегированность сегмента инструкций, в котором размещает­ся подпрограмма обслуживания, должна быть выше привилегированно­сти текущей программы (DPLCPL). Нарушение этого правила приводит к исключению типа #GP. Поэтому рекомендуется подпрограммы обслуживания прерываний и исключений располагать в сегментах с уровнем привилегийDPL=0, чтобы избежать ситуации, когда при поступлении запроса прерывания или исключения уровень текущей программыCPLокажется меньше, чемDPLсегмента инструкций обработчика прерывания.

При возникновении прерывания процессор сохраняет в стеке следующую информацию:

  • Содержимое регистра SSпрерванной процедуры (если имеет место изменение уровня привилегий).

  • Содержимое регистра ESPпрерванной процедуры (если имеет место изменение уровня привилегий).

  • Содержимое регистра EFLAGS.

  • Содержимое регистра CS.

  • Содержимое регистра EIP.

  • Код ошибки (если он формируется для данного исключения).

Далее процессор устанавливает в регистре EFLAGSзначения признаковTF=VM=NT=0.

Единственное различие между использованием шлюза ловушки и шлюза прерывания состоит в том, как процессор поступает с признаком IF. Если вызов подпрограммы обслуживания производится через шлюз прерывания, то после сохранения в стеке содержимого регистраEFLAGS, процессор устанавливает значение признакаIF=0, запрещая маскируемые прерывания. Если переход к подпрограмме обслуживания осуществляется через шлюз ловушки, то значение признакаIFне изменяется.

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

  • поле IOPLвосстанавливается только, еслиCPL=0,

  • флаг IFизменяется только, еслиCPLIOPL.

Формат дескриптора шлюза задачи при реализации прерываний и исключений имеет обычный вид (рис.7.16). Когда прерывание обрабатывается через шлюз задачи, то процессор выполняет обычную процедуру переключения задач, как это описано вразд. 7.4.

При реализации некоторых исключений процессор заносит в стек код ошибки, формат которого приведен на рис. $.2. Заметим, что формат кода ошибки #PFнесколько другой и описан в следующем разделе.

31

16

15

3

2

1

0

Резервировано

Индекс селектора

TI

IDT

EXT

Рис. $.2. Формат кода ошибки

Индекс селектора (биты 15-3) - указывает на дескриптор, использование которого вызвало исключение. Биты IDT,TIуказывают на таблицу, в которой находится неверный дескриптор. ЕслиIDT=1, то дескриптор находится в таблицеIDT. ЕслиIDT=0, то размещение дескриптора определяется битом TI: еслиTI=0, то дескриптор находится в таблицеGDT, если ТI=1 - в таблицеLDT. Если ЕХТ=1, то исключение вызвано не выполняемой программой, а внешним сигналом прерывания.

$.2. Причины возникновения исключений

В предыдущих главах рассмотрены основные случаи, при которых реализуются различные виды исключений (табл. $.1). Поэтому в данном разделе ограничимся кратким обзором причин их возникновения.

Исключение 0 - деление на нуль (#DE).Возникает при выполнении инструкций DIV, IDIV,если делитель равен нулю, или если результат не может разместиться в операнд-приемник (превышает разрядность приемника).

Исключение 1 - исключение для отладки (#DB).В зависимости от типа аппаратной точки останова исключение #DBможет обслуживаться как ошибка или как ловушка. Возникает и обрабатывается как ловушка:

  • обращении к данным или портам ввода вывода;

  • в пошаговом режиме (при значении признака TF=1 в регистреEFLAGS) после выполнения каждой инструкции;

  • при переключении на задачу, в сегменте TSSкоторой, установлен бит Т=1 (см. раздел7.4);

  • при выполнении инструкции INT 1;

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

Прерывание 2 - немаскируемое прерывание.Возникает при поступлении внешнего сигналаNMI=1 на вход NMIпроцессора или приеме соответствующего сообщения по шинеAPIC. Это прерывание может быть вызвано как программное с помощью инструкции INT 2.

Исключение 3 - исключение программной точки останова (#BP).Имеет место при выполнении однобайтной инструкцииINT 3. ИнструкцияINT 3обычно вводится в текст отлаживаемой программы для ее останова и контроля текущих результатов выполнения.

Исключение 4 - переполнение (#OF).Это исключение вызывается с помощью инструкции INTO.Инструкция INTOпроверяет признакOFв регистреEFLAQSи реализует исключение #OFесли значение этого признакаOF=1.

Исключение 5 - превышение границы массива (#BR).Имеет место при выполнении инструкции BOUND,если содержимое проверяемого регистра выходит за указанные пределы (см. раздел3.2).

Исключение 6 - недействительныйкод операции (#UD). Возникает при попытке выполнить инструкцию, в коде которой обнаружено какое-либо из следующих нарушений:

  • указан неиспользуемый (резервированный) код операции;

  • используется неправильный способ адресации операнда;

  • указан код ММХ- или SSE- инструкций при установленном в регистре CR0 значении бита ЕМ=1;

  • выбраны коды инструкций LLDT, SLOT, LTR, STR, LSL, ARPL, VERR, VERWпри работе процессора в реальном режиме или режиме виртуального 8086;

  • префикс LOCKиспользуется с инструкцией, при выполнении которой не должен производиться захват шины;

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

Исключение 7 - процессор FPU недоступен (#NM).Реализуется в следующих случаях:

  • при попытке выполнить FPU инструкцию, когда в регистре CR0 установлено значение бита ЕМ=1;

  • при попытке выполнить FPU-,MMX- или SSE-инструкцию, когда в регистре CR0 установлено значение битаTS=1;

  • попытка выполнить инструкцию WAITили FWAIT,когда в регистре CR0 установлено значение битов МР=ТS=1.

Исключение 8 - двойная ошибка (#DF).Реализуется в случае, ко­гда при вызове подпрограммы обслуживания одного исключения выявляется другое. Если процессор не может обработать такие исключения последовательно, то генерируется исключение #DF. При этом в стек заносится код ошибки с нулевым значением всех битов. Чтобы определить исключения, которые могут обрабатываться последовательно, они разбиты на три класса (см. табл. $.1):B(benign- безвредные),C(contributory- усугубляющие) иP(page- страничные). В табл. $.3 указано, какие классы исключений могут обрабатываться последовательно, а какие вызовут исключение #DF. Если при вызове исключения #DFобнаруживается другое исключение, то процессор переходит в отключенное состояние (shutdown).

Таблица $.3.