Сегментация памяти — это метод управления памятью операционной системы , позволяющий разделить основную память компьютера на сегменты или разделы . В компьютерной системе , использующей сегментацию, ссылка на ячейку памяти включает в себя значение, идентифицирующее сегмент, и смещение (ячейку памяти) внутри этого сегмента. Сегменты или разделы также используются в объектных файлах скомпилированных программ, когда они связаны вместе в образ программы и когда образ загружается в память.
Сегменты обычно соответствуют естественным подразделениям программы, таким как отдельные процедуры или таблицы данных [1], поэтому сегментация обычно более заметна для программиста, чем просто постраничная организация . [2] Сегменты могут быть созданы для программных модулей или для классов использования памяти, таких как сегменты кода и сегменты данных . [3] Некоторые сегменты могут использоваться совместно разными программами. [1] [2]
Сегментация изначально была изобретена как метод, с помощью которого системное программное обеспечение могло изолировать программные процессы ( задачи ) и данные, которые они используют. Он был предназначен для повышения надежности систем, выполняющих несколько процессов одновременно. [4]
В системе, использующей сегментацию, адреса памяти компьютера состоят из идентификатора сегмента и смещения внутри сегмента. [3] Аппаратный блок управления памятью (MMU) отвечает за преобразование сегмента и смещения в физический адрес , а также за выполнение проверок, чтобы убедиться, что преобразование может быть выполнено и что ссылка на этот сегмент и смещение разрешена.
Каждый сегмент имеет длину и набор разрешений (например, чтение , запись , выполнение ), связанных с ним. [3] Процессу разрешено делать ссылку на сегмент только в том случае, если тип ссылки разрешен разрешениями и если смещение внутри сегмента находится в пределах диапазона, заданного длиной сегмента. В противном случае возникает аппаратное исключение , такое как ошибка сегментации .
Сегменты также могут использоваться для реализации виртуальной памяти . В этом случае с каждым сегментом связан флаг, указывающий, присутствует он в основной памяти или нет. Если осуществляется доступ к сегменту, которого нет в основной памяти, возникает исключение, и операционная система считывает сегмент в память из вторичного хранилища.
Сегментация — один из методов реализации защиты памяти . [5] Пейджинг — это еще один вариант, и их можно комбинировать. Размер сегмента памяти обычно не фиксирован и может составлять всего один байт . [6]
Сегментация была реализована несколькими способами на различном оборудовании, с подкачкой или без нее. Сегментация памяти Intel x86 не подходит ни для одной из моделей и обсуждается отдельно ниже, а также более подробно в отдельной статье.
С каждым сегментом связана информация, указывающая, где сегмент находится в памяти — база сегмента . Когда программа ссылается на ячейку памяти, к базе сегмента добавляется смещение для генерации адреса физической памяти.
Реализация виртуальной памяти в системе с использованием сегментации без подкачки требует, чтобы целые сегменты переключались между основной и вторичной памятью. Когда сегмент заменяется, операционная система должна выделить достаточно непрерывной свободной памяти для хранения всего сегмента. Часто фрагментация памяти возникает, если непрерывной памяти недостаточно, хотя в целом ее может быть достаточно.
Вместо местоположения в памяти информация о сегменте включает в себя адрес таблицы страниц для сегмента. Когда программа ссылается на ячейку памяти, смещение преобразуется в адрес памяти с использованием таблицы страниц. Сегмент можно расширить, выделив еще одну страницу памяти и добавив ее в таблицу страниц сегмента.
Реализация виртуальной памяти в системе с использованием сегментации с подкачкой обычно перемещает только отдельные страницы вперед и назад между основной памятью и вторичной памятью, аналогично страничной несегментированной системе. Страницы сегмента могут располагаться в любом месте основной памяти и не обязательно должны быть смежными. Обычно это приводит к уменьшению объема ввода/вывода между основным и дополнительным хранилищем и уменьшению фрагментации памяти.
Компьютер Burroughs Corporation B5000 был одним из первых, реализовавших сегментацию, и «возможно, первым коммерческим компьютером, обеспечивающим виртуальную память» [7] на основе сегментации. B5000 оснащен таблицей информации о сегментах, называемой справочной таблицей программ (PRT), которая используется для указания того, находится ли соответствующий сегмент в основной памяти, для сохранения базового адреса и размера сегмента. [8] Более поздний компьютер B6500 также реализовал сегментацию; версия его архитектуры до сих пор используется на серверах Unisys ClearPath Libra.
Компьютер GE 645 , модификация GE-635 с добавленной поддержкой сегментации и пейджинга, был разработан в 1964 году для поддержки Multics .
Intel iAPX 432 [9] , начатый в 1975 году, пытался реализовать настоящую сегментированную архитектуру с защитой памяти на микропроцессоре.
Версия 960MX процессоров Intel i960 поддерживала инструкции загрузки и сохранения, при этом источник или место назначения являлись «дескриптором доступа» для объекта и смещением в объекте, при этом дескриптор доступа находился в 32-битном регистре и со смещением. вычисляется на основе базового смещения в следующем регистре и дополнительного смещения и, необязательно, индексного регистра, указанного в инструкции. Дескриптор доступа содержит биты разрешения и 26-битный индекс объекта; индекс объекта — это индекс в таблице дескрипторов объектов, указывающий тип объекта, длину объекта и физический адрес для данных объекта, таблицу страниц для объекта или таблицу страниц верхнего уровня для двухуровневого таблица страниц объекта в зависимости от типа объекта. [10]
Компьютеры Prime , Stratus , Apollo , IBM System/38 и IBM AS/400 (включая IBM i ) используют сегментацию памяти.
Дескрипторы в B5000 , B5500 и B5700 находятся либо в справочной таблице программ (PRT), либо в стеке и содержат бит присутствия, указывающий, присутствуют ли данные в памяти. Существуют отдельные дескрипторы данных и программ.
В моделях IBM System/370 [a] с виртуальной памятью [11] [12] (DAT) и 24-битными адресами регистр управления 0 определяет размер сегмента 64 КиБ или 1 МиБ и размер страницы либо 2 КиБ. или 4 КиБ; Регистр управления 1 содержит указатель таблицы сегментов (STD), который определяет длину и реальный адрес таблицы сегментов. Каждая запись таблицы сегментов содержит местоположение таблицы страниц, длину таблицы страниц и недопустимый бит. Позже IBM увеличила размер адреса до 31 бита и добавила два бита к записям таблицы сегментов:
Каждая из реализаций DAT от IBM включает в себя кэш трансляции, который IBM назвала буфером перевода (TLB). Хотя в разделе «Принципы работы» TLB рассматривается в общих чертах, детали не являются частью архитектуры и варьируются от модели к модели.
Начиная с процессорных комплексов 3031, 3032 и 3033 , IBM предложила функцию под названием « Двухадресное пространство» [12] : 5-13–5-17, Управление двухадресным пространством : 5-17–5-20, Авторизация DAS. Механизмы : 5-21–5-24, преобразование номеров ПК [13] (DAS), которое позволяет программе переключаться между таблицами трансляции для двух адресных пространств, называемых первичным адресным пространством (CR1) и вторичным адресным пространством ( CR7), а также для перемещения данных между адресными пространствами, на которые распространяется действие ключа защиты. DAS поддерживает таблицу трансляции для преобразования 16-битного номера адресного пространства (ASN) в STD с привилегированными инструкциями для загрузки STD в CR1 (первичный) или CR7 (вторичный).
Ранние процессоры 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-битную адресацию, сохраняет сегментацию и добавляет подкачку памяти . В этих процессорах таблица сегментов не указывает на таблицу страниц сегмента, а содержит адрес сегмента в линейной памяти . Когда подкачка включена, адреса в линейной памяти затем сопоставляются с физическими адресами с использованием отдельной таблицы страниц. Большинство операционных систем не использовали возможность сегментации, несмотря на возможные преимущества (логическое адресное пространство 4 x 4 ГБ вместо всего лишь 4 ГБ), предпочитая всегда сохранять базовый адрес во всех регистрах сегмента равным 0 и обеспечивать постраничную защиту памяти. и обмен с использованием только подкачки. Некоторые используют регистр CS для обеспечения защиты исполняемого пространства на процессорах, не имеющих бита NX , или используют регистры FS или GS для доступа к локальному хранилищу потоков. [14] [15]
Архитектура x86-64 не поддерживает сегментацию в « длинном режиме » (64-битном режиме). [16] Четыре сегментных регистра: CS, SS, DS и ES принудительно устанавливаются в 0, а предел — в 2 64 . Сегментные регистры FS и GS могут по-прежнему иметь ненулевой базовый адрес. Это позволяет операционным системам использовать эти сегменты для специальных целей, таких как локальное хранилище потоков. [14] [15]