Для большинства многопользовательских ОС, таких как Unix, подобная реализация неприемлема. Вместо того, чтобы предоставить пользовательской программе возможность прямой адресации виртуальной памяти, такие системы передают программе адрес, который перед использованием транслируется в виртуальный аппаратно. В архитектуре PowerPC такой адрес называется эффективным. Как мы увидим далее, эффективный адрес позволяет добиться некоторого уровня разделения памяти, но за счет больших накладных расходов.
Виртуальная память в таких системах логически подразделяется на сегменты — блоки последовательных байтов памяти. Эффективный адрес задает один из таких сегментов. Обычно трансляция эффективного адреса в виртуальный использует несколько (от 4 до 16) регистров микросхемы процессора, которые называются сегментными регистрами. Каждый сегментный регистр содержит виртуальный адрес одного из сегментов памяти. Часть старших разрядов эффективного адреса задают один из сегментных регистров. Остальные же задают байт внутри сегмента (и называются смещением в сегменте). Так как эффективный адрес содержит смещение внутри сегмента виртуального адреса, то данный тип адресации иногда называется адресацией относительно сегмента.
Проще всего представить себе эффективный адрес как подмножество виртуального адреса большего размера. Пользовательская программа может напрямую адресовать лишь несколько сегментов виртуальной памяти — те, чьи адреса загружены в сегментные регистры. Программа может запросить у ОС перезагрузку системных регистров, что позволит ей получить доступ к другим сегментам, но по-прежнему будет работать лишь с небольшой частью виртуальной памяти. Например, на некоторых процессорах Intel — лишь четыре сегментных регистра, что позволяет работать только с четырьмя сегментами одновременно, тогда как некоторые ранние процессоры RS/6000 использовали 16 таких регистров, но все равно могли адресовать лишь небольшую часть общей памяти.
В архитектуре PowerPC мы избавились от сегментных регистров и заменили их специальной таблицей в памяти, так называемой таблицей сегментов. Это дает пользовательским программам доступ к гораздо большему числу сегментов, чем регистровая реализация. Каждая запись таблицы сегментов по-прежнему содержит виртуальный адрес одного из сегментов виртуальной памяти. Эффективный адрес, используемый программой, теперь задает запись таблицы сегментов и байтовое смещение в сегменте. Две программы могут использовать совместно один и тот же виртуальный адрес, если они обращаются к одной и той же записи в таблице сегментов, или если тот же самый виртуальный адрес хранится в нескольких записях таблицы.
В случае адресации относительно сегмента, пользовательской программе виден только эффективный адрес, и таким образом, она не может сохранить где-либо виртуальный адрес. Трансляция эффективного адреса в виртуальный требует дополнительных накладных расходов, но зато виртуальные адреса защищены и не нужна «сборка мусора». Так как только ОС может изменять значения сегментных регистров, то в определенной степени контролируется, какие сегменты пользовательская программа может использовать и разделять с другими программами.
Поскольку эффективный адрес содержит только идентификацию записи таблицы сегментов и смещение адреса, постольку эффективный адрес имеет меньше разрядов, чем виртуальный. Именно благодаря тому, что виртуальный адрес не ограничен размером регистров процессора, 32-разрядный процессор с 32-разрядным виртуальным адресом может поддерживать большее виртуальное адресное пространство. Но даже и в этом случае, эффективный адрес может адресовать лишь подмножество адресного пространства без перезагрузки ОС сегментных регистров. Кроме того, хотя виртуальный адрес может иметь длину более 32 разрядов, отдельная операция по-прежнему использует только 32 разряда адреса. Таким образом, ограничение в 4 ГБ по-прежнему сохраняется, независимо от того, сколько разрядов в виртуальном адресе. Это объясняет, почему даже системы, поддерживающие большие виртуальные адреса, переходят с 32- на 64-разрядные процессоры.
Теперь сопоставим рассмотренную нами адресацию относительно сегмента с одноуровневой памятью AS/400. Одноуровневая память и виртуальные адреса располагаются ниже MI и не видны пользователю. Таким образом, для защиты адресов не требуется дополнительный уровень трансляции (эффективного адреса в виртуальный), она осуществляется с помощью указателей. Защищая указатели (с помощью разрядов тега), не надо идти на дополнительные накладные расходы, связанные с загрузкой и сохранением таблиц сегментов для каждой программы.
Читать дальше