Адресация в защищенном режиме 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Адресация в защищенном режиме



Прежде чем познакомиться с программированием в защищенном режиме, рассмотрим механизм адресации, применяющийся в нем. Так же как и в реальном режиме, адрес складывается из адреса начала сегмента и относительного смещения, но если в реальном режиме адрес начала сегмента просто лежал в соответствующем сегментном регистре, деленый на 16, то в защищенном режиме не все так просто. В сегментных регистрах находятся специальные 16-битные структуры, называемые селекторами и имеющие следующий вид:

биты 15 – 3: номер дескриптора в таблице

бит 2: индикатор таблицы 0/1 — использовать GDT/LDT

биты 1 – 0: уровень привилегий запроса (RPL)

Уровень привилегий запроса — это число от 0 до 3, указывающее уровень защиты сегмента, для доступа к которому используется данный селектор. Если программа имеет более высокий уровень привилегий, при использовании этого сегмента привилегии понизятся до RPL. Уровни привилегий и весь механизм защиты в защищенном режиме нам пока не потребуется.

GDT и LDT — таблицы глобальных и локальных дескрипторов соответственно. Это таблицы восьмибайтных структур, называемых дескрипторами сегментов, в которых и находится начальный адрес сегмента вместе с другой важной информацией:

слово 3 (старшее):

биты 15 – 8: биты 31 – 24 базы

бит 7: бит гранулярности (0 — лимит в байтах, 1 — лимит в 4-килобайтных единицах)

бит 6: бит разрядности (0/1 — 16-битный/32-битный сегмент)

бит 5: 0

бит 4: зарезервировано для операционной системы

биты 3 – 0: биты 19 – 16 лимита

слово 2:

бит 15: бит присутствия сегмента

биты 14 – 13: уровень привилегий дескриптора (DPL)

бит 12: тип дескриптора (0 — системный, 1 — обычный)

биты 11 – 8: тип сегмента

биты 7 – 0: биты 23 – 16 базы

слово 1: биты 15 – 0 базы

слово 0 (младшее): биты 15 – 0 лимита

Два основных поля в этой структуре, которые нам интересны, — это база и лимит сегмента. База представляет линейный 32-битный адрес начала сегмента, а лимит — это 20-битное число, которое равно размеру сегмента в байтах (от 1 байта до 1 мегабайта), если бит гранулярности сброшен в ноль, или в единицах по 4096 байт (от 4 Кб до 4 Гб), если он установлен в 1. Числа отсчитываются от нуля, так что лимит 0 соответствует сегменту длиной 1 байт, точно так же, как база 0 соответствует первому байту памяти.

Остальные элементы дескриптора выполняют следующие функции:

Бит разрядности: для сегмента кода этот бит указывает на разрядность операндов и адресов по умолчанию. То есть в сегменте с этим битом, установленным в 1, все команды будут интерпретироваться как 32-битные, а префиксы изменения разрядности адреса или операнда будут превращать их в 16-битные, и наоборот. Для сегментов данных этот бит управляет тем, какой регистр (SP или ESP) используют команды, работающие с этим сегментом данных как со стеком.

Поле DPL определяет уровень привилегий сегмента.

Бит присутствия указывает, что сегмент реально есть в памяти. Операционная система может выгрузить содержимое сегмента из памяти на диск и сбросить этот бит, а когда программа попытается к нему обратиться, произойдет исключение, обработчик которого снова загрузит содержимое этого сегмента в память.

Бит типа дескриптора — если он равен 1, сегмент является обычным сегментом кода или данных. Если этот бит — 0, дескриптор является одним из 16 возможных видов, определяемых полем типа сегмента.

Тип сегмента: для системных регистров в этом поле находится число от 0 до 15, определяющее тип сегментов (LDT, TSS, различные шлюзы), которые рассмотрены в главе 9. Для обычных сегментов кода и данных эти четыре бита выполняют следующие функции:

бит 11: 0 — сегмент данных, 1 — сегмент кода

бит 10: для данных — бит направления роста сегмента
для кода — бит подчинения

бит 9: для данных — бит разрешения записи
для кода — бит разрешения чтения

бит 8: бит обращения

Бит обращения устанавливается в 1 при загрузке селектора этого сегмента в регистр.

Бит разрешения чтения/записи выбирает разрешаемые операции с сегментом — для сегмента кода это могут быть выполнение или выполнение/чтение, а для сегмента данных — чтение или чтение/запись.

Бит подчинения указывает, что данный сегмент кода является подчиненным. Это значит, что программа с низким уровнем привилегий может передать управление в этот сегмент и текущий уровень привилегий не изменится.

Бит направления роста сегмента обращает смысл лимита сегмента. В сегментах с этим битом, сброшенным в ноль, допустимы все смещения от 0 до лимита, а если этот бит — 1, то допустимы все смещения, кроме смещений от 0 до лимита. Про такой сегмент говорят, что он растет сверху вниз, так как если лимит, например, равен –100, допустимы смещения от –100 до 0, а если лимит увеличить, станут допустимыми еще меньшие смещения.

Интерфейс VCPI

Спецификация этого интерфейса была создана в 1989 году, вскоре после появления процессора 80386, компаниями Phar Lap Software и Quaterdeck Office Systems. Программа, пользующаяся VCPI для переключения в защищенный режим, должна поддерживать полный набор системных таблиц — GDT, LDT, IDT, таблицы страниц и т.д., то есть фактически VCPI-сервер обеспечивает следующее — процессор находится в защищенном режиме, и различные программы, пользующиеся им, не будут конфликтовать между собой.

VCPI является своего рода расширением интерфейса EMS, и все обращения к нему выполняются при помощи прерывания EMS, INT 67h с АН = 0DEh и кодом подфункции VCPI в AL.

INT 67h АХ = DE00h — Проверка наличия VCPI

Ввод: AX = 0DE00h
Вывод: АН = 00, если VCPI есть ВН, BL — версия (старшая, младшая цифры)

INT 67h АХ = DE01h — Получить точку входа VCPI

Ввод: AX = 0DE01h ES:DI = адрес 4-килобайтного буфера для таблицы страниц DS:SI = адрес таблицы дескрипторов
Вывод: АН = 0, если нет ошибок DS:SI — первые три дескриптора заполняются дескрипторами VCPI-сервера ES:SI — адрес первой не используемой сервером записи в таблице страниц ЕВХ — адрес точки входа VCPI относительно сегмента, дескриптор которого лежит первым в таблице DS:SI. Можно делать far call из 32-битного защищенного режима на этот адрес с АХ = DE00h – DE05h, чтобы пользоваться функциями VCPI из защищенного режима

INT 67h AX = DE0Ch — VCPI: переключиться в защищенный режим (для вызова из V86)

Ввод: AX = 0DE0Ch ESI = линейный адрес таблицы со значениями для системных регистров (в первом мегабайте) +00h: 4 байта — новое значение CR3 +04h: 4 байта — адрес 6-байтного значения для GDTR +08h: 4 байта — адрес 6-байтного значения для IDTR +0Ch: 2 байта — LDTR +0Eh: 2 байта — TR +10h: 6 байт — CS:EIP — адрес точки входа прерывания должны быть запрещены
Вывод: Загружаются регистры GDTR, IDTR, LDTR, TR. Теряются регистры ЕАХ, ESI, DS, ES, FS, GS. SS:ESP указывает на стек размером в 16 байт, и его надо изменить, прежде чем снова разрешать прерывания

Точка входа VCPI, АХ = DE0Ch — Переключиться в режим V86 (для вызова из РМ)

Ввод: Перед передачей управления командой call в стек надо поместить регистры в следующем порядке (все значения — двойные слова): GS, FS, DS, ES, SS, ESP, 0, CS, EIP. Прерывания должны быть запрещены
Вывод: Сегментные регистры загружаются, значение ЕАХ не определено, прерывания запрещены

Остальные функции VCPI:

INT 67h AX = DE02h — Определить максимальный физический адрес

Ввод: АХ = 0DE02h
Вывод: АН = 0, если нет ошибок EDX = физический адрес самой старшей 4-килобайтной страницы, которую можно выделить

INT 67h AX = DE03h — Определить число свободных страниц

Ввод: АХ = 0DE03h
Вывод: АН = 0, если нет ошибок EDX = число свободных 4-килобайтных страниц для всех задач

INT 67h AX = DE04h — Выделить 4-килобайтную страницу (обязательно надо вызвать DE05h)

Ввод: АХ = 0DE04h
Вывод: АН = 0, если нет ошибок EDX = физический адрес выделенной страницы

INT 67h AX = DE05h — Освободить 4-килобайтную страницу

Ввод: АХ = 0DE05h EDX = физический адрес страницы
Вывод: АН = 0, если нет ошибок

INT 67h AX = DE06h — Определить физический адрес 4-килобайтной страницы в первом мегабайте

Ввод: АХ = 0DE06h СХ = линейный адрес страницы, сдвинутый вправо на 12 бит
Вывод: АН = 0, если нет ошибок EDX = физический адрес страницы

INT 67h AX = DE07h — Прочитать регистр CR0

Ввод: АХ = 0DE07h
Вывод: АН = 0, если нет ошибок ЕВХ = содержимое регистра CR0

INT 67h АХ = DE08h — Прочитать регистры DR0 – DR7

Ввод: АХ = 0DE08h ES:DI = буфер на 8 двойных слов
Вывод: АН = 0, если нет ошибок, в буфер не записываются DR4 и DR5

INT 67h AX = DE09h — Записать регистры DR0 – DR7

Ввод: АХ = 0DE09h ES:DI = буфер на 8 двойных слов с новыми значениями для регистров
Вывод: АН = 0, если нет ошибок (DR4 и DR5 не записываются)

INT 67h AX = DE0Ah — Определить отображение аппаратных прерываний

Ввод: АХ = 0DE0Ah
Вывод: АН = 0, если нет ошибок ВХ = номер обработчика для IRQ0 СХ = номер обработчика для IRQ8

INT 67h AX = DE0Bh — Сообщить VCPI-серверу новое отображение аппаратных прерываний (вызывается после перепрограммирования контроллера прерываний)

Ввод: АХ = 0DE0Bh ВХ = номер обработчика для IRQ0 СХ = номер обработчика для IRQ8
Вывод: АН = 0, если нет ошибок

Итак, чтобы использовать защищенный режим с VCPI, фактически надо уметь программировать его самостоятельно. Например, чтобы вызвать прерывание DOS или BIOS, нам пришлось бы переключаться в режим V86, вызывать прерывание и затем возвращаться обратно. Естественно, этот интерфейс не получил широкого развития и был практически повсеместно вытеснен более удобным DPMI.

Интерфейс DPMI

Спецификация DPMI создана в 1990 – 1991 годах и представляет собой развитую систему сервисов, позволяющих программам переключаться в защищенный режим, вызывать обработчики прерываний BIOS и DOS, передавать управление другим процедурам, работающим в реальном режиме, устанавливать обработчики аппаратных и программных прерываний и исключений, работать с памятью с разделяемым доступом, устанавливать точки останова и т.д. Операционные системы, такие как Windows 95 или, например, Linux, предоставляют DPMI-интерфейс для программ, запускаемый в DOS-задачах; многочисленные расширители DOS, о которых говорится в следующей главе, предоставляют DPMI для DOS-программ, запускаемых в любых условиях, так что сейчас можно считать DPMI основным интерфейсом, на который следует ориентироваться при программировании 32-битных приложений для DOS.



Поделиться:


Последнее изменение этой страницы: 2017-02-06; просмотров: 305; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.207.98.249 (0.014 с.)