Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка.doc
Скачиваний:
617
Добавлен:
22.05.2015
Размер:
2.56 Mб
Скачать

4.3.2 Дескрипторные регистры

GDTR (Global Descriptor Table Register – регистр глобальной дескрипторной таблицы) – специальный 48-битный регистр, который описывает местоположение и размер таблицы, содержащей дескрипторы. Он появился вместе с механизмом защиты в 80286 моделях процессоров как сегментный механизм защиты.

Регистр содержит два поля: первое поле – первые 32 бита, описывают физический адрес, по которому должна быть расположена дескрипторная таблица, а последние 16 бит – лимит, ограничение, которое накладывается на верхний дескриптор. Каждый дескриптор занимает в памяти по 8 байт, потому лимит всегда должен вычисляться так: limit = 8n ‑ 1, где n – количество дескрипторов.

При инициализации операционной системы глобальная дескрипторная таблица обычно создаётся на полное количество дескрипторов (limit = 65535), или 8192 дескрипторов. Затем вычисляется физический адрес начала таблицы, и загружается регистр GDTR специальной ассемблерной инструкцией LGDT (Load GDT):

mov AX, GDT_Limit

push AX

mov EAX, GDT_Base

push EAX

mov BP, SP

LGDT qword [SS:BP] ; Не забывайте, что стек растёт “вниз”!

После включения механизма защиты начинает действовать селекторная система адресации, вместо сегментной, и использоваться GDT.

LDTR (Local Descriptor Table Register – регистр локальной таблицы дескрипторов) – специальный 16-битный регистр, содержащий селектор сегмента LDT. Расположение в памяти и размер определяются соответствующими полями дескриптора. В настоящее время LDT используются только для выполнения 16-разрядных приложений.

Загрузка регистра LDTR осуществляется привилегированной командой LLDT (Load LDT):

LLDT word LDT_Seg

На 64-разрядных процессорах программы выполняются только в режиме памяти flat. Поэтому LDT не поддерживаются вовсе.

4.3.3 Дескриптор

Дескриптор несёт в себе полную информацию о сегменте: местоположение, уровень доступа, размер, принадлежность и т.д. Длина дескриптора равна восьми байтам. По информации, находящейся в дескрипторе, операционная система определяет линейные адреса сегментов программы. Структура дескриптора изображена на рисунке 4.2.

Биты поля доступа имеют следующий смысл:

  • Флаг гранулярности G определяет размер гранул, составляющих сегмент: при G=0 размер гранулы равен значению соответствующего поля в дескрипторе, а при G=1 размер гранулы равен полю дескриптора, умноженному на (212 = 4096). Таким образом, при G=0 максимальный размер сегмента 1 Мб, а при G=1 максимальный размер сегмента 4 Гб.

  • Флаг разрядности DB актуален для пользовательских сегментов кода и стека. Определяет разрядность сегмента в 16 бит при нулевом и 32 бит при единичном значении.

  • Зарезервированный флаг Res должен всегда равняться нулю.

  • Пользовательский флаг A отдан операционной системе. Его состояние никак не влияет на работу с сегментом.

  • Бит P определяет доступность сегмента (0 – сегмента нет, 1 – есть). При обращении к сегменту со сброшенным битом P происходит исключение #NP, обработчик которого может загрузить/создать сегмент.

  • Номер привилегий DPL содержит 2-битный номер (от 0 до 3), определяющий, к какому уровню (кольцу) защиты относится этот сегмент.

  • Тип сегмента определяется пятью битами. Из них старший бит (S) определяет сегмент как системный (S=0) или пользовательский (S=1). Значение остальных бит Type для системных и пользовательских сегментов описано в таблицах 4.1 и 4.2.

Младший бит байта AR пользовательских сегментов (A – Accessed,) можно использовать для сбора статистики о сегменте. При первом же обращении к сегменту (чтение, запись, выполнение) он устанавливается процессором в 1.

Таблица 4.1. Типы системных сегментов

Типы системных сегментов (при S=0)

Биты AR

Описание

3

2

1

0

0

0

0

0

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

0

0

0

1

Свободный 16-битный TSS

0

0

1

0

LDT

0

0

1

1

Занятый 16-битный TSS

0

1

0

0

16-битный шлюз вызова

0

1

0

1

Шлюз задачи

0

1

1

0

16-битный шлюз прерывания

0

1

1

1

16-битный шлюз ловушки

1

0

0

0

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

1

0

0

1

Свободный 32-битный TSS

1

0

1

0

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

1

0

1

1

Занятый 32-битный TSS

1

1

0

0

32-битный шлюз вызова

1

1

0

1

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

1

1

1

0

32-битный шлюз прерывания

1

1

1

1

32-битный шлюз ловушки

Таблица 4.2. Типы пользовательских сегментов

Биты AR

Описание

3

2

1

0

0

0

Сегмент данных только для чтения

0

0

1

Сегмент данных для чтения/записи

0

1

0

Сегмент данных только для чтения, растёт вниз

0

1

1

Сегмент данных для чтения/записи, растёт вниз

1

0

0

Сегмент кода только для выполнения

1

0

1

Сегмент кода для выполнения/чтения

1

1

0

Подчинённый сегмент кода только для выполнения

1

1

1

Подчинённый сегмент кода для выполнения/чтения