Лекции по Вычислительным машинам, системам и сетям   

3. Тридцатидвухразрядные процессоры фирмы Intel

3.11. Методы обработки прерываний, возникших в режиме V86

По терминологии фирмы Intel все прерывания делятся следующмим образом:

- немаскируемые аппаратные прерывания (NMI);

- маскируемые аппаратные прерывания (hardware interrupt);

- исключения (особые случаи) (exception);

- программные прерывания (команды int n) (software interrupt).

Используемый метод зависит от желания системного программиста, от возможностей процессора и от установки некоторых флагов и полей. Рассмотрим эти флаги и поля.

Поле IOPL (input-output privilege level) – это биты 12 и 13 регистра флагов ef. Когда процессор выполняет команду, которая является чувствительной к уровню привилегий, то он проверяет условие: текущий уровень привилегий задачи (CPL) должен быть не ниже IOPL:

CPL£IOPL.

Если это условие не выполняется, то возникает исключение #GP. Помните, что в режиме V86 CPL всегда равен 3!

В защищенном режиме к чувствительным командам относятся команды ввода/вывода (in; out; ins; outs) и команды, влияющие на состояние флага разрешения прерывания if (cli; sti). В режиме V86 к чувствительным относятся только команды: cli; sti; pushf; popf; int n и iret.

Флаг VME (0-й бит регистра cr4) (virtual mode extension – расширенный V86). Этот флаг появился в Pentium. 

Флаги VIF и VIP (соответственно, биты 19 и 20 в регистре флагов ef). Процессор, находясь в V86, работает с этими флагами только при VME = 1. VIF virtual interrupt flag (виртуальное разрешение прерываний). VIPvirtual interrupt pending (виртуальный флаг отложенного прерывания). Наличие этих флагов позволяет легче контролировать работу программ 86-го процессора, выполняющихся в V86 и меняющих состояние флага IF. То есть, если IOPL<3, то  программе не позволят менять IF, но, если доступен VIF, то позволят поменять VIF и при этом не будет #GP. Более подробно работа с этими флагами описана ниже.

Битовая карта перенаправления программных прерываний (Redirection bitmap). Используется только при VME = 1. Смысл здесь в следующем. Когда процессор находится в режиме V86, все прерывания (в том числе и программные по командам int n) переводят его в защищенный режим.

Чаще всего, когда обработчик защищенного режима определяет, что прерывание вызвано командой int n, возникшей в V86, то он возвращает это прерывание в V86 для его обработки стандартными средствами DOS и BIOS. На этих переключениях между режимами теряется время, поэтому, начиная с Pentium, была введена возможность (если VME = 1) сразу оставлять прерывания по некоторым командам int n для обработки в V86. Какие при этом команды сразу перенаправляются в V86, а какие идут в защищенный режим, определяют соответствующие биты битовой каты перенаправления. Каждый бит этой карты соответствует своему типу прерывания (n). Если бит = 1, то int n выводит в защищенный режим, если бит = 0, то int n обрабатывается в V86. То есть всего в этой карте 256 бит (32 байта). Располагается карта в TSS текущей задачи непосредственно перед битовой картой ввода/вывода (см. разд.  3.13). Таким образом, бит для int 0 имеет адрес:

База битовой карты ввода /вывода минус 32 байта.

Соответственно бит для int 255 имеет адрес:

База битовой карты ввода /вывода минус 1 бит.

Перейдем к методам обработки прерываний, возникающих в режиме V86. Все прерывания удобно разбить на три пересекающихся класса (т.е. одно и то же прерывание может входить сразу в несколько классов). Разбиение на классы приведено в табл.3.10.

Таблица 3.10

Класс 1

NMI

Маскируемые аппаратные внешние прерывания

Особые случаи

Программные прерывания

  Класс 2

Нет

Маскируемые аппаратные внешние прерывания

Нет

Нет

Класс 3

Нет

Нет

Нет

Программные прерывания

Существует три основных способа обработки Класса 1.

Первый способ заключается в следующей последовательности действий.

1. Произошло прерывание в режиме V86.

2. Процессор устанавливает TF = 0, VM = 0 и, если переход к обработчику происходит через шлюз прерываний, то IF = 0.

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

4. Процессор автоматически запоминает в новом стеке содержимое видимых частей сегментных регистров gs, fs, ds, es.

5. Процессор очищает эти регистры (сбрасывает в ноль).

6. Процессор запоминает в новом стеке ss:esp, ef, cs:eip и код ошибки, если, конечно, этот код есть.

7. Далее начинается работа системного программиста. Обработчик проверяет флаг VM (не в регистре ef, а в образе этого регистра, лежащем в стеке!) и определяет, что прерывание произошло в V86. Далее как раз и существуют три пути.

Первый путь. Обработать все в обработчике защищенного режима (в этом обработчике мы как раз сейчас и находимся) и, выполнив iret, вернуться в V86. При этом iret проверит VM (в образе ef в стеке) и восстановит все регистры надлежащим образом.

Второй путь. Обработчик вызывает командой call монитор V86 (обычно это специальная программа, тесно связанная с обработчиком #GP). Последний обрабатывает прерывание и возвращает (по ret) прерывание обработчику. Обработчик выполняет iret и т.д.

Третий путь связан с программными прерываниями, обработка которых имеет специфику и будет рассмотрена ниже.

Класс 2. К этому классу относятся маскируемые внешние аппаратные прерывания (hardware interrupt) при VME = 1, т.е. разрешены VIF и VIP и IOPL<3. Напомним о сути проблемы. Так как в V86 CPL = 3 (a IOPL<3) , то попытка выполнения команды, изменяющей значение флага IF, приведет к #GP. Действительно, программе можно разрешить менять этот флаг только в однозадачной системе. В многозадачной же системе запрет внешних прерываний какой-либо задачей может привести к монопольному захвату системы со стороны этой задачи. С другой стороны, многие задачи, написанные для 8086 и реального режима, работают с этим флагом. Если VME = 1, то то выполнение команды cli или sti, несмотря на IOPL<3, не приводит к #GP, хотя IF при этом не изменяется, но зато изменяется VIF.

Итак пусть IF = 1, а VIF = 0 и произошло аппаратное прерывание. Оно будет воспринято (так как IF = 1). Далее осуществляется та же последовательность действий, что и для Класса 1 (см. пп. 1 ‑ 7 для Класса 1).

8. Обработчик (знает, что это аппаратное прерывание, так как он обработчик этого аппаратного прерывания) проверяет флаг VIF (в образе, взятом из стека). Если этот флаг равен единице, то далее все идет обычным образом (как в Классе 1), если же этот флаг равен нулю, обработка прерывания не производится! В последнем случае обработчик просто устанавливает в хранящемся в стеке образе ef флаг VIP = 1 (имеется отложенное прерывание) и по iret уходит назад в V86.

Когда задача V86 установит флаг VIF (командой sti), то процессор проверит флаг VIP. Если при этом он окажется в единице, то произойдет #GP и отложенное прерывание можно будет обработать по Классу 1 с единственной отличительной чертой: перед возвратом в V86 надо установить VIP = 0 (в образе ef в стеке).

Класс 3. К классу 3 относятся программные прерывания (по int n). Программные прерывания могут также относиться к Классу1. В зависимости от значений флагов и полей можно выделить шесть методов обработки программных прерываний, показанных в табл. 3.11.

Метод 1. Программное прерывание обрабатывается в рамках Класса 1.

Metoд 2. Выполнениеint n приводит к #GP. Далее см. пп. 1 ‑ 7 для Класса 1. Обработчик #GP, определив, что прерывание пришло из V86, передает управление монитору V86, который есть часть обработчика #GP.

Таблица 3.11

Метод

VME

IOPL

Бит в карте перенаправления

1

0

3

Безразлично

2

0

<3

Безразлично

3

1

<3

1

4

1

3

1

5

1

3

0

6

1

<3

0

Монитор либо сам обрабатывает прерывание, либо, что чаще, передает его обратно в V86 для обработки средствами DOS и BIOS. Для этого монитор:

- находит в таблице прерываний V86 (не вIDT!!) вектор «местного» обработчика и по нему определяет начальный адрес этого обработчика;

- переписывает f, cs и eip, пришедшие из V86, из своего стека 0-го уровня в стек V86 (3-го уровня);

- подменяет в своем стеке 0-го уровня адрес возврата на найденный адрес обработчика V86;

- выполняет iret и мы в обработчике V86;

- когда обработчик V86 выполнит команду возврата iret, произойдет #GP (так как IOPL<3), то вновь окажемся в мониторе;

- восстановит адрес возврата;

- перепишет f из стека 3 в стек 0 (эта операция связана с тем, что многие DOS-обработчики возвращают результат в регистре флагов);

- выполнит iret для возврата в V86.

Метод 3. Полностью идентичен Методу 2.

Метод 4. Идентичен Методу 1.

Метод 5. Отличается от всего изложенного выше. Здесь нет перехода в защищенный режим, так как прерывание перенаправляется в V86 (остается и обрабатывается в V86 как в 8086). Действия процессора при этом тоже отличаются:

- процессор сохраняет в стеке (уровня 3) f с NT = 0 и IOPL = 0;

- процессор сохраняет в стеке cs иip;

- процессор устанавливает в f флагиTF = 0 иIF = 0;

- процессор берет вектор из таблицы V86 (не IDT) и переходит на обработчик, далее стандарт для 8086.

Метод 5 совпадает с обработкой прерываний в Реальном режиме.

Метод 6. Незначительно отличается от Метода 5 действиями процессора:

- сохраняет f сIOPL = 3 иIF = VIF;

- сохраняет cs иip;

- устанавливает VIF = TF = 0;

- переходит на обработчик.

При возврате по команде iret из Методов 5 и 6 процессор понимает, что он в режиме V86 по VM = 1. Сами Методы 5 и 6 он при этом не различает, но возврат получается правильным, поскольку флаги VIF, VIP, IOPL, VM при этом возврате не модифицируются.



*****
Новосибирск © 2009-2017 Банк лекций siblec.ru
Лекции для преподавателей и студентов. Формальные, технические, естественные, общественные, гуманитарные, и другие науки.