Введение

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

Внедрение аппаратного обеспечения

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

Сегментация без пейджирования

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

Сегментация с помощью пейджирования

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

История

Компьютер Burroughs Corporation B5000 был одним из первых, кто внедрил сегментацию, и, возможно, первым коммерческим компьютером, предоставившим виртуальную память на основе сегментации. B5000 оснащен таблицей информации о сегментах, называемой таблицей программных ссылок (PRT), которая используется для определения, находится ли соответствующий сегмент в основной памяти, а также для хранения базового адреса и размера сегмента. Позднее компьютер B6500 также реализовал сегментацию; версия его архитектуры до сих пор используется на серверах Unisys ClearPath Libra. Компьютер GE 645, представляющий собой модификацию GE 635 с добавленной поддержкой сегментации и страничной организации, был разработан в 1964 году для поддержки Multics. Intel iAPX 432, разработка которого началась в 1975 году, предпринял попытку реализовать полноценную сегментированную архитектуру с защитой памяти на микропроцессоре. Версия 960MX процессоров Intel i960 поддерживала команды загрузки и сохранения, в которых источником или назначением являлся "дескриптор доступа" к объекту и смещение внутри этого объекта, причем дескриптор доступа находился в 32-битном регистре, а смещение вычислялось на основе базового смещения в следующем регистре, дополнительного смещения и, опционально, индексного регистра, указанного в команде. Дескриптор доступа содержит биты разрешений и 26-битный индекс объекта; индекс объекта является индексом в таблицу дескрипторов объектов, предоставляющую тип объекта, длину объекта и физический адрес данных объекта, таблицу страниц для объекта или таблицу страниц верхнего уровня для двухуровневой таблицы страниц объекта, в зависимости от типа объекта. Компьютеры Prime, Stratus, Apollo, IBM System/38 и IBM AS/400 (включая IBM i) используют сегментацию памяти.

B5000

Описатели в B5000, B5500 и B5700 располагаются либо в таблице ссылок на программы (PRT), либо в стеке и содержат бит присутствия, указывающий, находятся ли данные в памяти. Существуют отдельные описатели данных и описатели программ.

Архитектура x86

Ранние процессоры x86, начиная с Intel 8086, обеспечивают примитивную сегментацию памяти и отсутствие защиты памяти. (Каждый байт каждого сегмента всегда доступен любой программе.) 16-битные сегментные регистры позволяют адресовать 65 536 сегментов; каждый сегмент начинается с фиксированного смещения, равного 16, умноженному на номер сегмента; гранулярность начального адреса сегмента составляет 16 байт. Каждый сегмент предоставляет доступ на чтение и запись к 64 КиБ (65 536 байт) адресного пространства (этот предел определяется 16-битными регистрами PC и SP; процессор не выполняет проверку границ). Сумма смещения и адреса, превышающая 0xFFFFF, переполняется до 0x00000. Каждый сегмент размером 64 КиБ перекрывает следующие 4095 сегментов; каждый физический адрес может быть представлен 4096 парами сегмент-смещение. Эта схема позволяет адресовать только 1 МиБ (1024 КиБ) физической памяти (и памяти, используемой для отображения устройств ввода/вывода). (Дополнительное оборудование для расширенной памяти может добавлять банковскую переключаемую память под управлением программного обеспечения.) Intel ретроспективно назвала единственный режим работы этих моделей процессоров x86 "реальным режимом". Процессоры Intel 80286 и более поздние добавляют "защищенный режим 286", который сохраняет 16-битное адресование и добавляет сегментацию (без постраничного обмена) и защиту памяти для каждого сегмента. Для обеспечения обратной совместимости все процессоры x86 загружаются в "реальном режиме" с теми же фиксированными перекрывающимися сегментами размером 64 КиБ, без защиты памяти, с объемом физического адресного пространства всего 1 МиБ и некоторыми незначительными отличиями (область высокой памяти, "нереальный режим"). Чтобы использовать полное 24-битное (16 МиБ) физическое адресное пространство и расширенные функции MMU, процессор 80286 или более поздний должен быть переключен в "защищенный режим" программным обеспечением, обычно операционной системой или DOS-расширителем. Если программа не использует сегментные регистры или помещает в них только значения, полученные от операционной системы, то один и тот же код может выполняться как в реальном, так и в защищенном режиме, но большинство программного обеспечения для реального режима вычисляет новые значения для сегментных регистров, нарушая эту совместимость. Процессоры Intel i386 и более поздние добавляют "защищенный режим 386", который использует 32-битное адресование, сохраняет сегментацию и добавляет постраничное разбиение памяти. В этих процессорах таблица сегментов, вместо указания на таблицу страниц для сегмента, содержит адрес сегмента в линейной памяти. При включенном постраничном обмене адреса в линейной памяти затем отображаются на физические адреса с использованием отдельной таблицы страниц. Большинство операционных систем не использовали возможности сегментации, предпочитая поддерживать базовый адрес во всех сегментных регистрах равным 0 и обеспечивать защиту памяти и обмен страницами только с помощью постраничного обмена. Некоторые используют регистр CS для обеспечения защиты исполняемого пространства на процессорах, не имеющих бита NX, или регистры FS или GS для доступа к локальному хранилищу потоков. Архитектура x86-64 не поддерживает сегментацию в "длинном режиме" (64-битном режиме). Четыре сегментных регистра: CS, SS, DS и ES принудительно устанавливаются в 0, а предел – в 264. Сегментные регистры FS и GS все еще могут иметь ненулевой базовый адрес. Это позволяет операционным системам использовать эти сегменты для специальных целей, таких как локальное хранилище потоков.