Операционная система Microsoft Windows 3.1 для программиста -том 3

         

Адресация памяти в защищенном режиме


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

Рис. 2.3. получение физического адреса в процессоре 80286

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

Таким образом, несмотря на то, что компоненты адреса остались, как и в реальном режиме, 16-разрядными, новая схема адресации защищенного режима процессора 80286 позволяет адресовать до 16 Мбайт памяти, так как в результате преобразования получается 24-разрядный физический адрес.

Кроме индекса, используемого для выбора ячейки дескрипторной таблицы при формировании физического адреса, селектор содержит еще два поля (рис. 2.4).

Рис. 2.4. Формат селектора

Поле TI (Table Indicator ) используется для выбора таблицы дескрипторов. Как мы уже говорили, существуют таблицы дескрипторов двух типов. В любой момент времени может использоваться одна глобальная таблица дескрипторов и одна локальная таблица дескрипторов. Если бит TI равен 0, для выборки базового адреса используется глобальная таблица дескрипторов GDT, если 1 - локальная LDT.




Зачем нужно использовать дескрипторные таблицы двух типов?

В мультизадачной операционной системе можно использовать одну глобальную таблицу дескрипторов для описания областей памяти, принадлежащей операционной системе и несколько локальных таблиц дескрипторов для каждой задачи. В этом случае при соответствующей настройке базовых адресов можно изолировать адресные пространства операционной системы и отдельных задач. Если сделать так, что каждая задача будет пользоваться только своей таблицей дескрипторов, любая задача сможет адресоваться только к своим сегментам памяти, описанным в соответствующей таблице, и к сегментам памяти, описанным в глобальной таблице дескрипторов. В системе может существовать только одна глобальная таблица дескрипторов.



Поле RPL (Requested Privilege Level ) селектора содержит уровень привилегий, запрошенный программой при обращении к сегменту. Программа может обращаться только к таким сегментам, которые имеют соответствующий уровень привилегий. Поэтому программа не может, например, воспользоваться глобальной таблицей дескрипторов для получения доступа к описанным в ней системным сегментам, если она не обладает достаточным уровнем привилегий. На этом основана защита системных данных от разрушения (преднамеренного или в результате программной ошибки) со стороны прикладных программ.

Таблица дескрипторов содержит, помимо базового адреса сегмента, другую информацию, описывающую сегмент (рис. 2.5). Точный формат дескриптора, а также других структур данных и системных регистров, имеющих отношение к работе в защищенном режиме, вы можете найти в 6 томе "Библиотеки системного программиста".



Рис. 2.5. Формат дескриптора сегмента процессора 80286

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

Поэтому, создав, например, сегмент для хранения массива размером 100 байт, вы не сможете записать в него 101 байт или 10 Кбайт данных.

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

Что же касается привилегий, в процессорах 80ххх и Pentium существуют четыре уровня привилегий - от 0 до 3, причем наибольшие привилегии соответствуют уровню 0. Уровни привилегий часто называют также кольцами защиты (рис. 2.6).



Рис. 2.6. Кольца защиты

В кольце 0 обычно работает ядро операционной системы. Кольцо 1 соответствует уровню привилегий драйверов, кольцо 2 - системам, таким как системы управления базами данных. В наименее привилегированном кольце 3 располагаются прикладные программы, запускаемые пользователем.

Описанная выше схема распределения привилегий может изменяться от одной операционной системы к другой. В операционной системе Windows 3.1 в нулевом кольце располагаются только виртуальные драйверы, все остальные модули Windows, а также приложения, работают в кольце 3.

Процессоры 80386, 80486 и Pentium используют более сложную схему адресации памяти, которая, однако, остается прозрачной для программиста.

Преобразование адреса в этих процессорах является многоступенчатым. Программы адресуют память с помощью логического адреса, состоящего из 16-разрядного селектора и 32-разрядного смещения. Так же, как и в процессоре 80286, селектор используется для выборки базового адреса сегмента из глобальной или локальной таблицы дескрипторов. Отличие заключается в том, что во-первых, используются 32-разрядные базовый адрес и смещение, а во-вторых, результат сложения называется линейным адресом и используется не для непосредственной адресации памяти, а для дальнейших преобразований (рис. 2.7).





Рис. 2.7. Преобразование логического адреса в линейный

Старшие десять бит линейного адреса используются как индекс в каталоге таблиц страниц (рис. 2.8).



Рис. 2.8. Преобразование линейного адреса в физический

В каталоге таблиц страниц хранятся дескрипторы, содержащие помимо другой информации, физические адреса таблиц страниц.

Следующие десять бит линейного адреса используются для выбора из таблицы страниц, адрес которой определяется старшими десятью битами линейного адреса.

Таблица страниц может описывать до 1024 страниц размером 4096 байт.

Младшие двенадцать бит линейного адреса содержат смещение адресуемого байта внутри страницы.

Отметим, что преобразование линейного адреса в физический выполняется процессором с помощью каталога таблиц страниц и таблиц страниц , подготовленных операционной системой. Программист, создающий приложения для Windows, никогда не работает с таблицами страниц или каталогом таблиц страниц. Он пользуется логическим адресом в формате <селектор:смещение>, поэтому схема преобразования логического адреса в физический остается для него прозрачной.

Операционная система Microsoft Windows версии 3.1 может работать, как вы знаете, в стандартном и расширенном режиме . В первом случае используется схема адресации процессора 80286, даже если в компьютере установлен процессор 80386. Если Windows работает на процессоре 80386, 80486 или Pentium, при наличии достаточного объема оперативной памяти (больше 2 Мбайт) по умолчанию используется расширенный режим работы и, соответственно, схема преобразования адресов процессора 80386.

Основное преимущество системы управления памятью расширенного режима работы Windows заключается в использовании виртуальной памяти. Виртуальная память работает на уровне страниц (описанных в каталогах страниц) и совершенно прозрачна для программиста. Операционная система Windows полностью управляет виртуальной памятью. Если программа пытается обратиться к странице, отсутствующей в памяти и выгруженной на диск, происходит прерывание работы программы, страница подгружается с диска, вслед за чем работа программы продолжается.


Программа может заказывать для себя блоки памяти огромного размера, адресуясь к ним непосредственно, при этом возникает полная иллюзия работы с оперативной памятью большого размера.

Описанная выше схема адресации в защищенном режиме накладывает ограничения на операции, которое приложение Windows может выполнять над селекторами.

Приложение Windows не должно выполнять над селекторами арифметические операции и операции сравнения

Программируя для реального режима операционной системы MS-DOS, вы, возможно, при адресации блока памяти большого размера (больше 64 Кбайт) изменяли содержимое сегментных регистров. В защищенном режиме вы не можете делать никаких предположений относительно базового адреса следующего или предыдущего дескриптора в локальной или глобальной таблице дескрипторов.

Сказанное не означает, что приложения Windows не могут работать с блоками памяти, занимающими несколько сегментов. В этом случае для адресации вам нужно использовать специальные методы. Однако, если вы составляете приложение на языке программирования С или С++, при определении указателей на блоки памяти размером больше, чем 64 Кбайт, можно воспользоваться ключевым словом huge. Для таких указателей при необходимости будет автоматически выполняться переключение на нужные селекторы.

Работа приложения Windows не должна зависеть от уровня привилегий, предоставленного приложению операционной системой, так как в новых версиях Windows этот уровень может измениться.

Приведем исходный текст приложения SELECTOR, с помощью которого вы сможете проанализировать структуру селектора сегмента кода и сегмента данных, взятых из регистров CS и DS (листинг 2.1).


Содержание раздела