Защищённый режим:

Глава 4. Дескриптор.

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

биты:
 0..15: предел, биты 0..15
16..31: адрес сегмента, биты 0..15
32..39: адрес сегмента, биты 16..23
    40: бит A (Accessed)
41..43: Тип сегмента
    44: бит S (System)
 45,46: DPL (Descriptor Privilege Level)
    47: бит P (Present)
48..51: предел, биты 16..19
    52: бит U (User)
    53: бит X (reserved)
    54: бит D (Default size)
    55: бит G (Granularity)
56..63: адрес сегмента, биты 24..31

        Эта структура поясняется на рис. 4-1:


Рисунок 4-1. Структура дескриптора.

        Как видите, значения предела и адреса сегмента "разбросаны" по всей структуре дескриптора. Это объясняется тем, что впервые защищённый режим появился в 16-разрядном процессоре 80286 и для совместимости с ним дескриптор не переделывали, а расширили дополнительными полями (биты с 49 по 63), благодаря чему программы, написанные для защищённого режима 286-го процессора работают и на 32-разрядных процессорах.
        Практически, в программах формат дескриптора удобнее использовать в следующем виде:

descriptor:
	dw	limit_low		; младшее слово предела
	dw	address_low		; младшее слово адреса
	db	address_hi		; 3-й (из четырёх) байт адреса
	db	access_rights		; права доступа
	db	limit_hi_and_flags	; старшая часть предела и флаги GDXU
	db	address_hi		; 4-й байт адреса

        Байт прав доступа имеет следующий формат:

биты:
   0: бит A (Accessed)
1..3: тип сегмента
   4: бит S (System)
 5,6: поле DPL
   7: бит P (Present)

        Байт старшей части предела и флагов GDXU имеет формат:

биты:
0..3: старшая часть предела (биты 16..19)
   4: бит U
   5: бит X
   6: бит D
   7: бит G

        Элементы дескриптора.

  •  
  • Адрес сегмента - также называется базовым адресом, - 32-разрядный адрес области памяти, с которой начинается сегмент.
  •  
  • Предел сегмента - предельное значение смещения в сегменте; также можно рассматривать предел как размер сегмента минус один элемент размера - байт или страницу, смотря в чём измеряется сегмент.
  •  
  • Бит A (Acessed) - бит доступа в сегмент. Этот бит показывает, был ли произведен доступ к сегменту, описываемому этим дескриптором, или нет. Если процессор обращался к сегменту для чтения или записи данных или для выполнения кода, размещённых в нём, то бит A будет установлен (равен 1), иначе - сброшен (0).
        С помощью бита A операционная система может определить, использовался ли за последнее время этот сегмент или нет и предпринять какие-либо действия.
        Бит A процессором только устанавливается, сбрасывать его должна операционная система.
        При создании нового дескриптора подразумевается, что бит A будет равен 0 (т.е. обращений к этому сегменту ещё не было).
  •  
  • Тип сегмента - трёхбитовое поле, определяющее тип сегмента (см. таблицу 4-1). Каждый бит типа сегмента имеет следующие значения:
  • старший бит (3-й бит в байте прав доступа):
    если 0, то это сегмент данных, если 1 - то кода
  • средний бит (2-й бит) - W (write-enable) бит разрешения записи:
    если 0, то запись запрещена, 1 - разрешена
  • младший бит (1-й бит) - E (expansion-direction) направление расширения сегмента:
    если 0, то вверх (в сторону старших адресов) - как обычно,
    если 1, то вниз (в сторону младших адресов) - как в стеке.

            Для сегмента кода значения битов W и E интерпретируются несколько иначе (см. таблицу 4-1)

  • Таблица 4-1. Тип сегмента

    Бит # 11 10 9 Тип  
    Название   E W
      0 0 0 Данные Только чтение
    0 0 1 Данные Чтение и запись
    0 1 0 Данные Только чтение, расширяется вниз
    0 1 1 Данные Чтение и запись, расширяется вниз
      1 0 0 Код Только выполнение
    1 0 1 Код Только выполнение
    1 1 0 Код Только выполнение, согласованный
    1 1 1 Код Выполнение и считывание, согласованный

    Примечания:
    1. В защищённом режиме процессор запрещает запись в сегмент кода и, как видно из таблицы, не всегда разрешает даже простое считывание (хотя, запись в сегмент кода, конечно же, можно сделать, но не явно)
    2. Согласованный сегмент кода будет обсуждаться в следующих главах.

  • Бит S (System) - определяет системный объект. Если этот бит установлен, то дескриптор определяет сегмент кода или данных, а если сброшен, то системный объект (например, сегмент состояния задачи, локальную дескрипторную таблицу, шлюз).
  • Поле DPL (Descriptor Privilege Level) - Уровень привилегий, который имеет объект, описываемый данным дескриптором. Это двухбитовое поле, в него при создании дескриптора записывают значения от 0 до 3, определяющее уровень привилегий.
        Например, Если вам нужно, чтобы процессор выполнял программу на нулевом уровне привилегий, то в DPL дескриптора сегмента кода, где размещается программа, должно быть значение 00B.
  • Бит P (Present) - Присутствие сегмента в памяти. Если этот бит установлен, то сегмент есть в памяти, если сброшен, то его нет. Этот бит применяется при реализации механизма виртуальной памяти - если программе понадобится память, то она сохранит содержимое какого-либо сегмента на диск и сбросит бит P. Если любая программа в дальнейшем обратится к этому сегменту, то процессор сгенерирует исключение неприсутствующего сегмента и запустит обработчик этой ситуации, который должен будет подгрузить содержимое сегмента с диска и установить бит P. После этого управление снова передаётся команде, обратившейся к этому сегменту (производится повторное выполнение команды, вызвавшей сбой) и работа программы будет продолжена. Бит P устанавливается и сбрасывается программами, сам процессор его только считывает.
  • Бит U (User) - Бит пользователя. Этот бит процессор не использует и позволяет программе использовать его в своих целях.
  • Бит X (rezerved) - Зарезервированный бит. Intel не рекомендует использовать этот бит, так как он может понадобится в более поздних моделях процессоров.
  • Бит D (Default size) - Размер операндов по умолчанию. Если бит сброшен, по процессор использует объект, описываемый данным дескриптором, как 16-разрядный, если бит установлен - то как 32-разрядный. Если ваша программа имеет 32-разрядный код, то он должен размещаться в 32-разрядном сегменте кода (т.е. в дескрипторе такого сегмента бит D должен быть равен 1). В защищённом режиме допускается использование одновременно 16- и 32-разрядных сегментов, но при написании новых программ подразумевается, что все сегменты будут 32-разрядные. Подробнее об этом см. в главе "Смешивание 16- и 32-разрядного кода".
  • Бит G (Granularity) - Гранулярность сегмента, т.е. единицы измерения его размера. Если бит G=0, то сегмент имеет байтную гранулярность, иначе - страничную (одна страница - это 4Кб).
        Например, сегмент, имеющий предел, равный 2, при G=0 будет иметь размер в три байта, а при G=1 - 12Кб (3 страницы)

            Создавать дескрипторы достаточно легко. Все биты и битовые поля находятся в байте прав доступа access_rights (P, DPL, S, Тип, A ) и в старших четырёх разрядах байта limit_hi_and_flags (G, D, X, U). Дескрипторы по типу отличаются значениями байта прав доступа, по свойствам - битами G и D, остальное - значения базового адреса и предела. Когда мы будем рассматривать пример перехода в защищённый режим, вы увидите один из вариантов конструирования дескрипторов.

    Следующая глава Оглавление Вопросы? Замечания? Пишите: sasm@narod.ru

      Copyright © Александр Семенко.
    TopList

    Hosted by uCoz