Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Финогенов-основы_языка_ассемблера.doc
Скачиваний:
46
Добавлен:
17.09.2019
Размер:
3.35 Mб
Скачать

Глава 4

4 Кбайт

4 Кбайт

4 Кбайт

4 Кбайт

4 Кбайт

4 Кбайт

4 Кбайт

4 Кбайт

Линейное адресное пространство

Физическое адресное пространство

Рис. 4.6. Отображение логических адресов на физические.

31

Страничный кадр

Каталог страниц 1024 4х-байтовых полей

Линейный адрес

2221 12 Ц

Физический адрес

12 11

Смещение

Таблица страниц

CR3

Каждая таблица содержит 1024 4х-байтовых полей

Базовый адрес каталога

Рис. 4.7. Страничная трансляция адресов.

расширенные возможности современных микропроцессоров 181

Не все 1024 таблицы страниц должны обязательно иметься в наличии (кстати, они заняли бы в памяти довольно много места — 4 Мбайт). Если программа реально использует лишь часть возможного линейного адрес­ного пространства, а так всегда и бывает, то неиспользуемые поля в ката­логе страниц помечаются, как отсутствующие. Для таких полей система, экономя память, не выделяет страничные таблицы.

При включенной страничной трансляции линейный адрес рассмат­ривается, как совокупность трех полей: 10-битового индекса в каталоге страниц, 10-битового индекса в выбранной таблице страниц и 12-битово­го смещения в выбранной странице. Напомним, что линейный адрес об­разуется путем сложения базового адреса сегмента, взятого из дескрипто­ра сегмента, и смещения в этом сегменте, предоставленного программой.

Старшие 10 бит линейного адреса образуют номер поля в каталоге страниц. Базовый адрес каталога хранится в одном из управляющих реги­стров процессора, конкретно, в регистре CR3. Из-за того, что каталог сам представляет собой страницу и выровнен в памяти на границу 4 Кбайт, в регистре CR3 для адресации к каталогу используются лишь старшие 20 бит, а младшие 12 бит зарезервированы для будущих применений.

Поля каталога имеют размер 4 байт, поэтому индекс, извлеченный из линейного адреса, сдвигается влево на 2 бит (т.е. умножается на 4) и полу­ченная величина складывается с базовым адресом каталога, образуя адрес конкретного поля каталога. Каждое поле каталога содержит физический базовый адрес одной из таблиц страниц, причем, поскольку таблицы стра­ниц сами представляют собой страницы и выровнены в памяти на границу 4 Кбайт, в этом адресе значащими являются только старшие 20 бит.

Далее из линейного адреса извлекается средняя часть (биты 12...21), сдвигается влево на 2 бит и складывается с базовым адресом, хранящим­ся в выбранном поле каталога. В результате образуется физический адрес страницы в памяти, в котором опять же используются только старшие 20 бит. Этот адрес, рассматриваемый, как старшие 20 бит физического адре­са адресуемой ячейки, носит название страничного кадра. Страничный кадр дополняется с правой стороны младшими 12 битами линейного ад­реса, которые проходят через страничный механизм без изменения и иг­рают роль смещения внутри выбранной физической страницы.

Рассмотрим абстрактный пример, позволяющий проследить цепочку преобразования виртуального адреса в физический. Пусть программа вы­полняет команду

mov EAX,DS:[EBX]

при этом содержимое DS (селектор) составляет 1167h, а содержимое ЕВХ (смещение) 31678h.

Старшие 13 бит селектора (число 116U) образуют индекс дескриптора в системной дескрипторной таблице. Каждый дескриптор включает в себя довольно большой объем информации о конкретном сегменте и, в част­ности, его линейный адрес. Пусть в ячейке дескрипторной таблицы с но­мером 116h записан линейный адрес (базовый адрес сегмента) 01051000h.

182

Глава -t

Тогда полный линейный адрес адресуемой ячейки определится, как сум­ма базового адреса и смещения:

Базовый адрес сегмента 01051000h Смещение 00031678h

Полный линейный адрес 01082678h

При выключенной табличной трансляции величина 01082678U будет представлять собой абсолютный физический адрес ячейки, содержимое которой должно быть прочитано приведенной выше командой mov. Легко сообразить, что эта ячейка находится в самом начале 17-го мегабайта оперативной памяти.

Посмотрим, как будет образовываться физический адрес при использо­вании страничной трансляции адресов. Полученный линейный адрес надо разделить на три состаатяющис для выделения индексов и смещения (рис. 4.8)

31

22 21

1211

О

| 0000000100 I 0010000010 | 01100111 1000 I

Индекс каталога Индекс таблицы Смещение

страниц Рис, 4.8. Пример линейного адреса.

Индекс каталога составляет 4h. Умножение его на 4 даст смещение от начала каталога. Это смещение равно 10h.

Индекс таблицы страниц оказался равным 82h. После умножения на 4 получаем смещение в таблице страниц, равное в данном случае 210h.

Предположим, что регистр CR3 содержит число 80001г. Тогда физичес­кий адрес ячейки в каталоге, откуда надо получить адрес закрепленной за данным участком программы таблицы страниц, составит SOOOh + 10h = 8010h. Пусть по этому адресу записано число 460211г. Его 12 младших битов составляют служебную информацию (в частности, бит 1 свидетельствует о присутствии этой таблицы страниц в памяти, а бит 5 говорит о том, что к этой таблице уже были обращения), а старшие биты, т.е. число 46000h образуют физический базовый адрес таблицы страниц. Для получения ад­реса требуемой ячейки этой таблицы к базовому адресу надо прибавить смещение 210U. Результирующий адрес составит 462101г.

Будем считать, что по адресу 46210h записано число 01FF5021h. От­бросив служебные биты, получим адрес физической страницы в памяти 01FF5000U. Этот адрес всегда оканчивается тремя нулями, так как страни­цы выровнены в памяти на границу' 4 Кбайт. Для получения физического адреса адресуемой ячейки следует заполнить 12 младших бит полученного адреса битами смещения из линейного адреса нашей ячейки, в которых в нашем примере записано число 678U. В итоге получаем физический адрес памяти 01FF5678h, расположенный в конце 32-го Мбайта.

Как видно из этого примера, и со страничной трансляцией, и без нее вычисление физических адресов адресуемых ячеек выполняется в защи­щенном режиме совсем не так, как в реальном. Неприятным практичес-

расширенные возможности современных микропроцессоров

183

ким следствием правил адресации защищенного режима является уже упоминавшаяся «оторванность» прикладной программы от физической памяти. Программист, отлаживающий программу защищенного режима (например, приложение Windows), может легко заглянуть в сегментные регистры и определить селекторы, выделенные программе. Однако селек­торы абсолютно ничего не говорят о физических адресах, используемых программой. Физические адреса находятся в таблицах дескрипторов, а эти таблицы недоступны прикладной программе. Таким образом, програм­мист не знает, где в памяти находится его программа или используемые ею области данных.

С другой стороны, использование в процессе преобразования адресов защищенных системой таблиц имеет свои преимущества. Обычно много­задачная операционная система создает для каждой выполняемой задачи свой набор таблиц преобразования адресов. Это позволяет каждой из за­дач использовать весь диапазон виртуальных адресов, при этом, хотя для разных задач виртуальные адреса могут совпадать (и, как правило, по край­ней мере частично совпадают), однако сегментное и страничное преобра­зования обеспечивают выделение для каждой задачи несовпадающих об­ластей физической памяти, надежно изолируя виртуальные адресные про­странства задач друг от друга.

Вернемся теперь к таблицам дескрипторов и рассмотрим их более де-тально. Существует два типа дескрипторных таблиц: таблица глобальных дескрипторов (GDT от Global Descriptor Table) и таблицы локальных дескрипторов (LDT от Local Descriptor Table).Обычно для каждой из этих таблиц в памяти создаются отдельные сегменты, хотя в принципе это не обязательно. Таблица глобальных дескрипторов существует в единствен­ном экземпляре и обычно принадлежит операционной системе, а локаль­ных таблиц может быть много (это типично для многозадачного режима, в котором каждой задаче назначается своя локальная таблица).

Виртуальное адресное пространство делится на две равные половины. К одной половине обращение происходит через GDT, к другой половине через LDT. Как уже отмечалось, все виртуальное пространство состоит из 214 сегментов, из которых 213 сегментов адресуются через GDT, и еще 213 - чрез LDT.

Когда многозадачная система переключает задачи, глобальная таблица остается неизменной, а текущая локальная таблица заменяется на локаль­ную таблицу новой задачи. Таким образом, половина виртуачьного про­странства в принципе доступна всем задачам в система, а половина пере­ключается от одной задачи к другой по мере переключения самих задач.

Для программирования защищенного режима и даже для отладки при­кладных программ, работающих в защищенном режиме, полезно пред­ставлять себе структуру дескриптора и смысл его отдельных полей. Следу­ет заметить, что существует несколько типов дескрипторов, которым при­сущи разные форматы. Так, дескриптор сегмента памяти (наиболее распространенный тип дескриптора) отличается от дескриптора шлюза, используемого, в частности, для обслуживания прерываний. Рассмотрим формат дескриптора памяти (рис. 4.9).

184

Глава -f

Байты

7

.6 5

4

3210

База 31. ..24

•\триб\ты

2'

Атрибуты Г

База сегмента 23...0 rP™mja сегмента i i i

Биты 765

/< 43210

765

Ч

Биты 43210

G

D

0

А V

L

1 1 1

Граница

19...16 i i i

i Р DPL

1

Тип i i

А

Рис. 4.9. Формат дескриптора памяти.

Как видно из рисунка, дескриптор занимает 8 байт. В байтах 2..,4 и 7 записывается линейный базовый адрес сегмента. Полная длина базового адреса — 32 бит. В байтах 0-1 записываются младшие 16 бит границы сег­мента, а в младшие четыре бита байта атрибутов 2 — оставшиеся биты 16...19. Границей сегмента называется номер его последнего байта. Мы видим, что граница описывается 20-ю битами, и ее численное значение не может превышать 1М. Однако, единицы, в которых задается граница, можно изменять, что осуществляется с помощью бита дробности G (бит 7 байта атрибутов 2). Если G=0, граница указывается в байтах; если 1 — в блоках по 4 Кбайт. Таким образом, размер сегмента можно задавать с точ­ностью до байта, но тогда он не может быть больше 1 Мбайт; если же установить G=l, то сегмент может достигать 4 Гбайт, однако его размер будет кратен 4 Кбайт. База сегмента и в том, и в другом случае задастся с точностью до байта.

Рассмотрим теперь атрибуты сегмента, которые занимают два байта дескриптора.

Бит A (Accessed, было обращение) устанавливается процессором в тот момент, когда в какой-либо сегмс!ггаый регистр загружается селектор данного сегмента. Далее процессор этот бит не сбрасывает, однако его может сбросить программа (разумеется, если она имеет доступ к содержи­мому дескриптора, что обычно является прерогативой операционной си­стемы). Анализируя биты обращения различных сегментов, программа может судить о том, было ли обращение к данному сегменту после того, как она сбросила бит А.

Тип сегмента занимает 3 бит (иногда бит А включают в поле типа, и тогда тип занимает 4 бит) и может иметь 8 значений. Тип определяет пра­вила доступа к сегменту. Так, если сегмент имеет тип 1, для него разреше­ны чтение и запись, что характерно для сегментов данных. Назначив сег­мент)' тип 0, мы разрешим только чтение этого сегмента, защитив его тем самым от любых модификаций. Тип 4 обозначает разрешение исполне­ния, что характерно для сегментов команд. Используются и другие типы сегментов.

Расширенные возможности современных микропроцессоров 185

Подчеркнем, что защита сегментов памяти от несанкционированных его типом действий выполняется не программой, и даже не операцион­ной системой, а процессором на аппаратном уровне. Так, при попытке записи в сегмент типа 0 возникнет так называемое исключение общей защиты. Исключением называется внутреннее прерывание, возбуждаемое процессором при возникновении каких-либо неправильных с его точки зрения ситуаций. Попытка записи в сегмент, для которого запись запре­щена, и относится к такого рода ситуациям. Исключению общей защиты соответствует вектор 13, в котором должен находиться адрес обработчика этого исключения.

Стоит еще обратить внимание на тип 4. Для сегмента команд разреша­ется только исполнение, но не запись и даже не чтение. Это значит, что в защищенном режиме программа не может случайно залезть в свой сег­мент команд и затереть его; не может она также и сознательно модифици­ровать команды в процессе своего выполнения — методика, иногда ис­пользуемая в программах реального режима для защиты от их расшифров­ки любознательными программистами.

Бит 4 байта атрибутов 1 является идентификатором сегмента. Если он равен 1, как это показано на рис. 4.9, дескриптор описывает сегмент памя­ти. Значение этого бита 0 характеризует дескриптор системного сегмента.

Поле DPL (Descriptor Privilege Level, уровень привилегий дескрипто­ра) служит для защиты программ друг от друга. Уровень привилегий мо­жет принимать значения от 0 (максимальные привилегии) до 3 (мини-матьные). Программам операционной системы обычно назначается уро­вень 0, прикладным программам — уровень 3, в результате чего исключается возможность некорректным программам разрушить операционную систе­му. С другой стороны, если прикладная программа сама выполняет функ­ции операционной системы, переводя процессор в защищенный режим и работая далее в этом режиме, ее сегментам следует назначить наивысший (нулевой) уровень привилегий, что откроет ей доступ ко всем средствам защищенного режима.

Бит Р говорит о присутствии сегмента в памяти. В основном он ис-

|j пользуется для организации виртуальной памяти. С помощью этого бита

система может определить, находится ли требуемый сегмент в памяти, и

при необходимости загрузить его с диска. В процессе выгрузки ненужного

пока сегмента на диск бит Р в его дескрипторе сбрасывается.

Младшая половина байта атрибутов 2 занята старшими битами грани­цы сегмента. Бит AVL (от Available, доступный) не используется и не анализируется процессором и предназначен для использования приклад­ными программами.

Бит D (Default, умолчание) определяет действующий по умолчанию

размер для операндов и адресов. Он изменяет характеристики сегментов

двух типов: исполняемых и стека. Если бит D сегмента команд равен 0, в

^сегменте по умолчанию используются 16-битовые адреса и операнды, если

1 — 32-битовые.

186