Возможности адресации памяти процессорами различных поколений
Сложность обращения к памяти в PC обусловлена свойствами процессоров х86 разных поколений и требованием обратной совместимости новых процессоров и компьютеров со старым ПО.
Процессорам 8086/88 было доступно адресное пространство 1 Мбайт с диапазоном адресов О-FFFFFh, причем физический 20-битный адрес вычислялся с помощью двух 16-битных компонентов по формуле Addr = Segxl6 + Offset, где Seg — содержимое сегментного регистра (CS, DS, SS или ES), a Offset — исполнительный адрес, формируемый из одного или нескольких слагаемых в соответствии с выбранным режимом адресации. Эта сегментная модель адресации позволяет программам оперировать с непрерывными блоками памяти (сегментами) размером не более 64 Кбайт. Для манипуляций с памятью большего размера требовалось переключение сегментов с помощью специальных инструкций процессора, что усложняло программирование. Заметим, что при Seg = FFFFh n Offset =• FFFFh данная формула дает адрес lOFFEFh, но ввиду 20-битного ограничения на шину адреса эта комбинация в физической памяти указывает на OFFEFh. Таким образом, адресное пространство как бы сворачивается в кольцо с небольшим «нахлестом».
В процессоре 80286 шина физического адреса была расширена до 24 бит, и введен новый режим работы — защищенный (Protected Mode), в котором программа может обращаться к 16-мегабайтному пространству физической памяти через логическое пространство виртуальной памяти. Здесь виртуальная память строилась на основе той же сегментной модели памяти с 16-разрядными регистрами. Физический адрес формировался суммированием 16-разрядного исполнительного адреса (смещения внутри сегмента) с 24-разрядным базовым адресом сегмента.
Кроме защищенного режима, в процессоре 80286 имеется и реальный режим, в котором процессор ведет себя почти так же, как и 8086 (но более быстрый). Здесь физический адрес вычисляется так же, как и в 8086/88, но из-за ошибки разработчиков та самая единица в бите А20, которая отбрасывалась в процессорах 8086/88, теперь попадает на шину адреса, и в результате максимально доступный физический адрес в реальном режиме достиг 1 OFFEFh.
Для обеспечения полной совместимости с процессором 8086/88 в схему PC ввели вентиль линии А20 шины адреса — GateA20, который либо пропускает сигнал от процессора, либо принудительно обнуляет линию А20 системной шины адреса. Этот вентиль должен быть открыт при работе в защищенном режиме, а также когда в реальном режиме нужны дополнительные (64 К-16) байт памяти. Вентиль управляется через контроллер клавиатуры (см. п. 8.1.2) или иным специфическим способом.
J5 32-разрядных процессорах, начиная с 80386, сохранена та же идея обращения к памяти с участием сегментных регистров (16-разрядных), но регистры процессора, участвующие в формировании адреса, позволяют адресовать уже 232= 4 Гбайт памяти в каждом сегменте. Базовый адрес сегмента берется из специальных структур данных — дескрипторов сегментов. Кроме базового адреса в дескрипторе описывается его лимит (длина), назначение (код или данные), возможность записи
470______ Глава 12. Архитектурные компоненты IBM PC-совместимого компьютера
и чтения, а также уровень привилегий программы, позволяющий обращаться к данному сегменту. Дескрипторы предварительно программно формируются в памяти, где их наборы хранятся в виде таблиц дескрипторов. Процессор имеет средства защиты памяти, контролирующие использование сегментов. Программа может обращаться лишь к тем сегментам памяти, описание которых имеется в доступных дескрипторах. Виртуальное адресное пространство, доступное программе, имеет объем до (16 К-2) сегментов (число возможных дескрипторов), каждый из которых может иметь размер до 4 Гбайт. Дескриптор выбирается с помощью селектора, загружаемого в сегментный регистр (CS, DS, SS, E5, F5 или GS). Однако это виртуальное адресное пространство отображается блоком сегментации в логическое адресное пространство с опять-таки 32-разрядным линейным адресом, то есть объемом 4 Гбайт. По замыслу разработчиков процессора, это отображение с подкачкой требуемых сегментов с диска и выгрузкой неиспользуемых должно выполняться диспетчером виртуальной памяти операционной системы.
Практически такая виртуализация применялась на процессорах 80286 (с 16-разрядными регистрами), поскольку иных механизмов не существовало.
Для виртуализации памяти (и защиты) в 32-разрядных процессорах применяется иной механизм, основанный на блоке страничной переадресации — принципиальной новинке 32-разрядных процессоров х86. В его задачу входит отображение 32-разрядного линейного адреса (продукта блока сегментации) на 32- или 36-разрядный физический адрес, формируемый на системной шине процессора при его обращениях к памяти. В отличие от блока сегментации, оперирующего блоками разного размера (сегментами), блок страничной переадресации оперирует страницами одинакового размера. Переадресация выполняется на основе таблиц страниц, где для каждой страницы логической памяти имеется свой описатель. В этом описателе имеется признак присутствия страницы в физической памяти, и для присутствующих страниц указывается базовый адрес физического отображения. Кроме того, имеются биты, управляющие доступом к странице по чтению и записи с различных уровней привилегий, возможностью ее кэширования, и некоторые служебные биты. При обращении программы к отсутствующей странице процессор вырабатывает исключение, обработчик которого занимается подкачкой нужной страницы из внешней памяти (с диска) в ОЗУ. Этот обработчик и реализует виртуальную память с подкачкой страниц по запросу (Demand-Paged Virtual Memory), которая в настоящее время обычно и подразумевается под виртуальной памятью. При недостатке свободного места в физической памяти обработчик выполняет и замещение страниц, по его мнению, наименее нужных, выгружая их на диск. Создав несколько наборов описателей страниц, можно получить несколько виртуальных адресных пространств, каждое из которых имеет размер до 4 Гбайт, причем страницы разных пространств могут быть полностью изолированы друг от друга, а могут и частично пересекаться. В многозадачной ОС каждая задача (виртуальная машина) имеет собственное (как ей представляется) адресное пространство.
Первоначально блок страничной переадресации работал со страницами размером 4 Кбайт. В дополнение к этому базовому механизму в процессор Pentium ввели возможность работы и со страницами размером 4 Мбайт (режим PSE). В ряде
12.5. Процессоры х86________________________________________________ 471
процессоров Р6 разрядность физического адреса увеличена до 36 бит, и все процессоры Р6 имеют возможность включение режима переадресации РАЕ, позволяющего отображать страницы размером 4 Кбайт и 2 Мбайт с расширением физического адреса. С процессорами Pentium III появился режим преобразования PSE-36, в котором блок оперирует 4-Мбайтными страницами в 36-битном физическом пространстве и сохраняется возможность работы со стандартными 4-Кбайтными страницами базового режима. Это позволяет довольно эффективно управляться с современными объемами физической памяти компьютера.
В стандартном реальном режиме 32-разрядные процессоры работают с памятью так же, как и 80286, с возможностью адресации в диапазоне О-lOFFEFh, причем вентиль Gate A20 ввели уже в сам процессор. Физический адрес вычисляется с участием сегментных регистров, размер непрерывного сегмента — 64 Кбайт. По умолчанию в реальном режиме адреса формируются с использованием только младших 16 бит 32-разрядных регистров, правда, для каждой инструкции можно с помощью префиксов изменить разрядность адресных компонентов на 32 бита. Однако и при этом невозможно пересечь границу 64-Кбайтного сегмента — срабо-' тает исключение защиты.
В стандартном реальном режиме блок страничной переадресации не работает, и физический адрес совпадает с линейным. С помощью временного переключения в защищенный режим можно настроить таблицы страниц, разрешить преобразование и далее в реальном режиме задействовать страничное преобразование. Этот трюк используется менеджерами памяти типа EMM386 для работы со свободными блоками UMA.
Есть и еще один режим, неофициальный, но тоже работающий на всех 32-разрядных процессорах х86, — «нереальный» (unreal), он же «большой реальный» (big real) .
Он позволяет процессору в реальном режиме обращаться к данным, расположенным в любом месте 4-Гбайтного пространства линейных ( и физических) адресов. Этот режим базируется на логике блока сегментации, которая при вычислении линейного адреса во время обращений к памяти пользуется скрытыми программно-недоступными регистрами дескрипторов сегментов. Из этих регистров берется базовый адрес, из них же берется и лимит, который используется схемой защиты. В этих регистрах кэшируются дескрипторы сегментов, загружаемые из памяти во время исполнения инструкций, переопределяющих значения сегментных регистров (CS, DS, SS, ES, FS и GS) в защищенном режиме. По аппаратному сбросу в эти скрытые регистры заносятся «неинтересные» параметры стандартного реального режима, с лимитом 64 Кбайт. В реальном режиме при переопределении сегментных регистров значение базового адреса берется как 16-кратное значение, загружаемое в соответствующий сегментный регистр, а лимит устанавливается в 64 Кбайт. Тем не менее, если в защищенном режиме в сегментный регистр загрузить селектор дескриптора, в котором описан сегмент размером 4 Гбайт с нулевым базовым адресом и возможностью полного доступа на любом уровне привилегий, переключиться в реальный режим и не трогать этот сегментный регистр, то далее процессор будет иметь доступ ко всему этому сегменту в данной модификации реального режима. Однако такая «благодать» распространяется
472______ Глава 12. Архитектурные компоненты IBM PC-совместимого компьютера
только лишь на доступ к данным через сегментные регистры F.S и GS, которые используются в инструкциях обращений к памяти, снабженных префиксами замены сегмента. Эти сегментные регистры появились только с 32-разрядными процессорами, и никакие традиционные сервисы BIOS (и DOS) их не затрагивают. Остальные сегментные регистры настолько часто используются, что «время жизни» описания большого сегмента в их кэширующих регистрах будет слишком коротким.
Программный код, увы, исполняется только из сегмента, которым командует CS, поэтому для него остается лишь первый мегабайт с 64-Кбайтными сегментами. Так что большие программные модули приходится подгружать в эту область по мере надобности, но это можно выполнять довольно быстро пересылками данных из любого места «большого сегмента». Большой реальный режим широко используется менеджерами памяти, а также игровыми DOS-программами, всецело захватывающими ресурсы компьютера.
Итак, самые широкие возможности адресации имеются в защищенном 32-разрядном режиме, наиболее естественном для современных процессоров. В этом режиме может использоваться как плоская, так и сегментная модели памяти. Под плоской (flat) понимается модель, в которой все сегментные регистры указывают на один и тот же сегмент памяти (как правило, начинающийся с нулевого адреса), и его лимит может достигать 4 Гбайт, что позволяет адресовать этот немалый (даже по нынешним меркам) объем памяти без манипуляций сегментными регистрами. Однако при этом теряются все возможности виртуализации памяти на основе сегментов, а также отсутствует сегментная защита. В сегментной модели памяти сегментные регистры кода, стека и данных настраиваются на разные, возможно и не пересекающиеся сегменты. Здесь имеются все возможности сегментной защиты и сегментной виртуализации памяти. Поскольку современным приложениям пока достаточно 4 Гбайт памяти (надолго ли?), сегментную модель ради упрощения диспетчера памяти стараются не использовать. Защита памяти имеется и на уровне страниц, правда, не такая развитая и надежная, как сегментная.