Дескриптор сегмента представляет собой структуру данных в памяти, которая сообщает процессору размер и расположение в памяти сегмента, а также управляющую информацию и информацию о состоянии сегмента. Дескрипторы обычно создаются компиляторами, компоновщиками, загрузчиками или операционной системой, но не прикладными программами. На Рисунке 5-8 показаны два общих формата дескриптора. Дескриптор системного сегмента более подробно рассматривается в Главе 6. Все типы дескрипторов системы имеют один из этих форматов.
База: Определяет расположение сегмента в пределах 4 гигабайтного физического адресного пространства. Процессор располагает вместе три поля базового адреса, которые образуют одно 32-битовое значение. Значения базы сегмента должны быть выравнены по кратным 16 байтам адресам памяти, что позволяет программам максимизировать их быстродействие, выравнивая в свою очередь по кратным 16 байтам адресам памяти код/данные.
Бит грануляции: Включает масштабирование поля Границы масштабным коэффициентом 4096(2**12). Если этот бит очищен, то граница сегмента интерпретируется в блоках по 4Кб (т.е. в страницах). Отметим, что двенадцать наименее значащих битов адреса в случае, если используется масштабирование, не тестируются. Например, граница 0 при установленном бите грануляции дает допустимые смещения от 0 до 4095. Отметим также, что этот коэффициент действует только на значение поля Границы. Базовый адрес остается гранулированным по байтам.
Дескрипторы, используемые для сегментов кода и данных прикладных программ:
2 2 2 2 2 1 1 1 1 1 1 1 1 1 131 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 0---------------------------------------------------------------| | | | |A| | | D | | | || BASE 31:24 |G|D|0|V| |P| P |S| TYPE | BASE 23:16 || | | | |L| | | L | | | ||-------------------------------------------------------------|| Базовый адрес 15:00 | Граница сегмента 15:00 |---------------------------------------------------------------
Дескрипторы, используемые для специальных системных сегментов:
2 2 2 2 2 1 1 1 1 1 1 1 1 1 131 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 0---------------------------------------------------------------| | | | |A| | | D | | | || BASE 31:24 |G|D|0|V| |P| P |S| TYPE | BASE 23:16 || | | | |L| | | L | | | ||-------------------------------------------------------------|| Базовый адрес 15:00 | Граница сегмента 15:00 |--------------------------------------------------------------- AVL Доступно для использования системным программным обеспечениемBASE Базовый адрес сегментаDPL Уровень привилегированности дескриптораS Тип дескриптора (0=системный; 1=прикладной)G ГрануляцияГраница Граница сегментаP Присутствие сегментаTYPE Тип сегментаD Размер операции по умолчанию (Распознается только в дескрипторах кодового сегмента: 0=16-битовый размер; 1=32-битовый размер) Рисунок 5-8 Дескрипторы сегмента
Граница: Определяет размер сегмента. Процессор помещает рядом два поля границы сегмента, в совокупности образующих одно 20-разрядное значение. Процессор интерпретирует границу одним из двух слудующих способов, в зависимости от установки бита грануляции:
Если бит грануляции очищен, то граница может принимать значения от 1 байта до 1 мегабайта, с приращениями в один байт.
Если бит грануляции установлен, то граница может принимать значения от 4 Килобайт до 4 Гигабайт, с приращениями в 4 Кб.
Для большинства сегментов логический адрес может иметь значение смещения в диапазоне от 0 до значения границы. Прочие значения ведут к генерации исключений. Сегменты с расширением вниз изменяют смысл поля граница на противоположный: они позволяют адресацию любыми значениями смещения, кроме значений от 0 до значения границы (см. описание поля Типа, приводимое ниже). Это позволяет создавать сегменты, для которых увеличение значения поля Границы приводит к распределению новой памяти в нижней части адресного пространства, вместо верхней. Сегменты с расширением вниз предназначены для хранения стеков, но использовать их не обязательно. Если стек должен быть помещен в сегмент, который не будет изменять свой размер, то таким сегментом может быть обычный сегмент данных.
Бит S: Определяет, является ли этот сегмент системным сегментом, или же сегментом кода или данных. Если бит S установлен, то сегмент является либо кодовым сегментом, либо сегментом данных. Если этот бит очищен, то сегмент является системным сегментом.
Бит D: Указывает длину операндов и исполнительных адресов сегмента по умолчанию. Если бит D установлен, то предполагается режим 32-разрядных операндов и 32-разрядных исполнительных адресов. Если этот бит очищен то предполагается использование 16-разрядных операндов и адресов.
Тип: Интерпретация этого поля зависит от того, относится ли данный дескриптор к прикладному, или же к системному сегменту. Системные сегменты имеют несколько иной формат дескриптора, рассматриваемый в Главе 6. Поле Типа дескриптора памяти задает тип доступа, разрешенного к данному сегменту, а также направление, в котором этот сегмент растет (см. Таблицу 5-1).
Таблица 5-1. Типы прикладных сегментов-----------------------------------------------------------------Число | E | W | A | Тип | Описание | | | |дескриптора|----------------------------------------------------------------- 0 0 0 0 Данные Только чтение 1 0 0 1 Данные Только чтение, выполнен доступ 2 0 1 0 Данные Чтение/запись 3 0 1 1 Данные Чтение/запись, выполнен доступ 4 1 0 0 Данные Только чтение, расширение вниз 5 1 0 1 Данные Только чтение, расширение вниз, выполнен доступ 6 1 1 0 Данные Чтение/запись, расширение вниз 7 1 1 1 Данные Чтение/запись, расширение вниз, выполнен доступ-----------------------------------------------------------------Число | C | R | A | Тип | Описание | | | |дескриптора|----------------------------------------------------------------- 8 0 0 0 Код Только выполнение 9 0 0 1 Код Только выполнение, выполнен доступ 10 0 1 0 Код Выполнение/чтение 11 0 1 1 Код Ваполнение/чтение, выполнен доступ 12 1 0 0 Код Только выполнение, конформный 13 1 0 1 Код Только выполнение, конформный, выполнен доступ 14 1 1 0 Код Выполнение/только чтение, конформный 15 1 1 1 Код Выполнение/только чтение, конформный, выполнен доступ-----------------------------------------------------------------
Для сегментов данных три младших бита поля типа можно интерпретировать как признаки расширения вниз (E), разрешения записи (W) и того, что к сегменту был выполнен доступ (A). Для кодовых сегментов три младших бита поля типа можно интерпретировать как признак конформности (C), разрешения чтения (R) и выполненного доступа (A).
Сегменты данных могут быть предназначены только для чтения или для чтения/записи. Загрузка регистра SS селектором сегмента для любого другого типа сегмента генерирует исключение общей защиты. Если стековому сегменту требуется иметь возможность изменять размер, то ему может быть назначен сегмент данных с типом расширения вниз. Для сегмента с расширением вниз смысл поля Границы меняется на противоположный. Если для других типов сегмента допустимыми являются значения смещения в диапазоне от 0 до значения границы (вне этого диапазона генерируется исключение общей защиты), то для сегмента с расширением вниз значения в этом диапазоне, напротив, ведут к генерации исключения. Допустимыми смещениями для сегментов с расширением вниз являются те, что для сегментов других типов вызывают особую ситуацию. Сегменты с расширением вверх должны адресоваться смещениями, меньшими или равными границе сегмента. Смещения же в сегменты с расширением вниз всегда должны превышать значение границы сегмента. Такая интерпретация границы сегмента вызывает распределение области памяти в нижней части сегмента, когда граница сегмента увеличивается, что является правильным для стековых сегментов, поскольку они растут в направлении младшего адреса. Если стек помещается в сегменте, который не меняет своего размера, то этот сегмент не обязан быть сегментом с расширением вниз.
Кодовые сегменты могут быть предназначены только для выполнения, либо для выполнения/чтения. Сегмент с типом "выполнение/чтение" может быть использован, например, когда в команды кода в ПЗУ помещены константы. В данном случае константы могут быть прочитаны либо при помощи команды, имеющей префикс переопределения сегмента CS, либо при помощи помещения селектора данного кодового сегмента в сегментный регистр для сегмента данных.
Кодовые сегменты могут быть либо конформными, либо не-конформными. Переход выполнения в более привилегированный конформный сегмент сохранит текущий уровень привилегированности. Переход выполнения в не-конформный сегмент с другим уровнем привилегированности приведет к генерации исключения общей защиты, если не использован шлюз задачи (обсуждение средств мультизадачности см. в Главе 6). Системные утилиты, не обращающиеся к средствам защиты, такие как функции транслирования данных (например, перекодировка EBCDIC/ASCII, кодирование / декодирование по методу Хафмана, библиотека математических функций), а также некоторые типы исключений (например, ошибка деления на ноль, переполнение, обнаруженное при помощи INTO или превышение диапазона BOUND) могут быть загружены в конформные кодовые сегменты.
Поле Типа также сообщает о том, был ли к данному сегменту выполнен доступ. В исходном состоянии дескрипторы сегментов сообщают о том, что доступ к сегменту был. Если поле Типа затем установить в значение, означающее, что доступ к сегменту не был выполнен, процессор восстановит значение, если доступ к сегменту произошел. Очистив и проверив младший бит поля Типа, программное обеспечение может контролировать использование сегмента (младший бит поля Типа также называется битом Доступа).
Например, система разработки программ может очистить все биты Доступа для сегментов прикладной программы. При сбое в прикладной программе состояния этих битов могут быть использованы для генерации карты всех сегментов, к которым выполнила доступ данная прикладная программа. В отличие от контрольных точек, которые обеспечиваются механизмом отладки (см. Главу 11), информация, предоставляемая этим полем, относится не к физическим адресам, а к сегментам.
Процессор может обновлять поле Типа при доступе к сегменту, даже если доступ этот произошел в цикле чтения. Если таблицы дескрипторов были помещены в ПЗУ, аппаратному обеспечению может потребоваться запретить связь ПЗУ с шиной данных во время цикла записи. Также может потребоваться возвратить сигнал READY# процессору в цикле записи в ПЗУ; в противном случае не произойдет завершение этого цикла. Эти средства аппаратной конструкции необходимы для использования ПЗУ-резидентных таблиц дескрипторов с процессором 386 DX, который всегда устанавливает бит Доступа при загрузке дескриптора сегмента. Однако, процессор i486 только в том случае, если он еще не установлен. Избежать попытки записи в таблицы дескрипторов в ПЗУ можно, установив биты Доступа в каждом дескрипторе.
DPL (Уровень привилегированности дескриптора): Определяет уровень привилегированности сегмента. Используется для управления доступом к сегменту при помощи механизма защиты, описанного в Главе 6.
Бит присутствия сегмента: Если этот бит очищен, то процессор при загрузке в сегментный регистр селектора данного дескриптора генерирует исключение "сегмент не присутствует". Это свойство используется для обнаружения попыток доступа к сегментам, которые стали недоступными. Сегмент может стать недоступным, когда системе понадобилось создать свободную память. Для элементов памяти, таких как символьные шрифты или драйверы устройств, в тех случаях, когда они в текущий момент не используются, выполняется отмена распределения памяти. Отмена распределения памяти такому элементу выполняется маркировкой такого сегмента как "не присутствующего" (это выполняется при помощи очистки бита присутствия сегмента). После этого память, занимаемая данным сегментом, может быть распределена для другого использования. Когда элемент, для которого было отменено распределение памяти, понадобится в следующий раз, исключение "сегмент не присутствует" укажет на то, что необходимо снова загрузить этот сегмент в память. Если такого рода организация памяти выполняется способом, не видимым для прикладных программ, то она называется "виртуальной памятью". Система может работать с общим размером виртуальной памяти, значительно превышающим физическую память, благодаря тому, что одновременно в физической памяти присутствует только несколько сегментов.
На Рисунке 5-9 показан формат дескриптора, когда бит присутствия сегмента очищен. В этом случае операционная система имеет право использовать адреса памяти, отмеченные как Доступная, для хранения там своих собственных данных, например, информации об отсутствующих сегментах.