Навигация сайта

  • Главная
  • Статьи
  • Учебники
  • Программы
  • Друзья сайта

Глава 3. Адресация памяти в защищённом режиме

Первое, с чем сталкивается программа при переходе в защищённый режим - это совершенно другая система адресации памяти. Для начала, давайте вспомним, как это происходит в режиме реальных адресов - для обращения к памяти используется пара 16-разрядных регистров - сегментный регистр и смещение.
В сегментном регистре находится адрес сегмента. Сегмент - это область памяти размером в 64 Кб, которая должна начинаться на границе параграфа или, другими словами, на 16-байтной границе, то есть сегмент может начинаться только по адресу 0, 16, 32, 48 и т.д. Адресное пространство процессора 8086 равно одному мегабайту - это адреса в диапазоне от 00000h до FFFFFh. Т.к. сегмент начинается по адресу, кратному 16 (10h), то возможные адреса начала сегмента будут 00000h, 00010h, 00020h, ... , FFFF0h. Как видите, информация содержится в старших четырёх шестнадцатеричных разрядах - их и хранят в сегментном регистре. Другими словами, можно взять значение из сегментного регистра, умножить его на 16 (т.е. на 10h) и вы получите адрес начала сегмента.
Для указания конкретного адреса внутри сегмента используется второй 16-разрядный регистр, так называемое смещение. Использование пары регистров сегмент:смещение обеспечивает доступ ко всему мегабайту адресного пространства.
Каждый раз, перед тем как процессор обратится к памяти по адресу, указанному в паре регистров сегмент:смещение, он вычисляет адрес памяти по следующей схеме:


физический_адрес = сегмент * 10h + смещение.

Осталось заметить, что, вообще говоря, в режиме реальных адресов адресное пространство немного больше одного мегабайта, а именно:


1Мб + 64Кб - 16 байт.
Такой адрес получается, если загрузить в пару регистров максимальные значения:
FFFF:FFFF

При этом адрес будет равен:


FFFFh * 10H + FFFFh = FFFF0h + FFFFh = 10FFEFh = 1114095

Теперь давайте рассмотрим схему образования адреса в защищённом режиме, как это происходит в процессоре i386 (80386 - это базовая модель для любого Pentium-а).
Адрес памяти в 32-разрядном процессоре является также 32-разрядным. Это значит, что адресное пространство для такого процессора равно 4 Гб (2 32 байт).
Адресация памяти также производится через сегмент и смещение в сегменте, для чего используется пара регистров, но для описания сегмента используется больше информации, а именно:

  • 32-разрядный адрес,
  • 20-разрядный предел сегмента (предел = размер - 1),
  • номер уровня привилегий сегмента,
  • тип сегмента (код, стек, данные или системный объект)
  • и дополнительные свойства, о которых подробнее будет сказано в других главах.

Как видите, информации об одном сегменте достаточно много. Для того, чтобы её хранить, используется не регистр, а специальная область памяти. Сегмент по-прежнему указывается в сегментном регистре, но теперь в нём хранится номер сегмента из списка определённых сегментов. Этот номер называется селектор.
В качестве смещения используется 16- или 32-разрядный регистр.
При обращении к памяти, процессор проверяет возможность доступа к сегменту по уровню привилегий, проверяет, не превысил ли адрес предел сегмента и можно ли обращаться к этому сегменту в данном случае (например, запрещена передача управления в сегмент, описывающий данные или стек). Если в результате проверки будет обнаружено нарушение какого-либо условия, то процессор сгенерирует исключение и тем самым обеспечит защиту.

Предел сегмента - это максимально допустимое смещение внутри него, таким образом, предел сегмента определяет его размер: размер_сегмента = предел_сегмента + 1

Обратите внимание, что значение предела - 20-разрядная величина, это значит, что максимальное значение предела равно 2 20 - 1.
Процессор измеряет размер сегмента двумя типами величин: либо байтами, либо страницами. Страница - это блок памяти размером в 4Кб.
В описании сегмента можно указать, в каких единицах измеряется сегмент и тогда можно получить два типа сегментов с максимальными размерами:

  • в 1Мб ( 2 20 байт ) или
  • в 4Гб ( 2 20 страниц = 2 20 * 4Кб = 2 20 * 2 12 = 2 32 байт )

    Эта способность измерять сегмент либо байтами, либо страницами, называется гранулярность.
    Значение предела сегмента может быть любым, от 0 до 2 20 - 1, гранулярность устанавливается по усмотрению программиста и может быть либо байтная, либо страничная. Всё это позволяет определять сегменты любого размера - от 0 байт до 4Гб.

  •  

    Техническая поддержка и аудит сайта.