§ Селектор
При адресации памяти в защищённом режиме команды ссылаются на сегменты, указывая не их адреса (как в режиме реальных адресов), а описания сегментов (их дескрипторы). Указатель на описание сегмента называется селектор. Другими словами, селектор - это номер дескриптора из таблицы дескрипторов.Адресация производится через пару регистров сегмент:смещение, причём, в качестве сегментного регистра используются обычные CS, SS, DS, ES, FS и GS (последние два появились в 386-м процессоре), но в них указывается не адрес сегмента, а селектор дескриптора.
Селекторы нужны, по крайней мере, по трём причинам:
- Описание сегмента занимает 8 байт и использовать 8-байтные сегментные регистры было бы крайне неэффективно
- Селекторы имеют размер в 16 бит, благодаря чему их можно использовать в сегментных регистрах и обращаться к памяти можно по-прежнему через пару регистров
- Параметры всех сегментов хранятся в отдельной области памяти, доступ к которой имеет только операционная система. Программа, используя селектор, сможет получить о сегменте совсем немного информации и не сможет изменить параметры сегмента, благодаря чему очень удачно реализуется механизм защиты
Можно было бы определить селектор просто, как номер сегмента, но в защищённом режиме кроме сегментов, дескриптор может определять целый ряд других системных объектов (например, задач), поэтому лучше не упрощайте понятия селектора и дескриптора, а постарайтесь привыкнуть к этой терминологии.
Селектор имеет следующий формат:
15 | 3 | 2 | 1 0 |
---|---|---|---|
Index | TI | RPL |
- Бит TI (Table Indicator) определяет таблицу, из которой выбирается нужный дескриптор. Если бит TI = 0, то обращение производится к глобальной дескрипторной таблице GDT (она одна на всю систему), если TI = 1 - то к текущей локальной дескрипторной таблице LDT (таких может быть много). Подробнее дескрипторные таблицы обсуждаются в соответствующих главах.
- Index - это собственной номер дескриптора, от 0 до 8191. Т.к. поле индекса состоит из 13 бит, то максимальное число дескрипторов, одновременно существующих в системе равно 213, т.е. 8192. Как видите, это довольно-таки много и вполне удовлетворяет любым системным запросам. На самом деле, число дескрипторов можно значительно увеличить за счёт использования множества дополнительных локальных дескрипторных таблиц.
Обращение к дескрипторной таблице процессор производит только в момент загрузки в сегментный регистр нового селектора. После этого содержимое дескриптора копируется в так называемый "теневой регистр", к которому имеет доступ только сам процессор и из которого оно в дальнейшем используется. Любое последующее обращение к сегменту будет происходить с помощью теневого регистра, без обращения к дескрипторной таблице и не потребует лишних тактов на циклы чтения памяти. Правда, эти такты тратятся каждый раз, когда вы загружаете новый селектор, но это не высокая плата за защиту дескрипторов от недозволенного доступа.
При загрузке недопустимого значения селектора процессор будет генерировать исключение, даже если вы не обращались через него к памяти.