Открыть сервис

Сегментная адресация

Сегментная адресация — это механизм управления памятью, при котором адресное пространство программы делится на логические блоки (сегменты) переменной длины, а каждый адрес представляется в виде пары, состоящей из номера сегмента и смещения внутри него. В отличие от страничной адресации, где память делится на блоки фиксированного размера (страницы), сегменты могут иметь произвольный размер, соответствующий логической структуре данных (код, данные, стек, куча). Сегментная адресация широко применялась в архитектурах x86 (режим реальных адресов и защищённый режим), а также в операционных системах (OS/2, Multics) и языках программирования (Intel 8086, IBM System/360).

История

Ранние реализации

Идея сегментации восходит к 1960-м годам, когда в компьютерах IBM System/360 была реализована адресация с использованием сегментов для поддержки многозадачности и защиты памяти. В 1970-х годах в операционной системе Multics (MIT, Bell Labs, General Electric) сегменты использовались как основной способ организации виртуальной памяти, позволяя программам обращаться к большим адресным пространствам, чем физически доступно.

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

Наибольшую известность сегментная адресация получила с появлением процессоров Intel 8086 (1978 год). В реальном режиме (Real Mode) 16-битные процессоры использовали сегментные регистры (CS, DS, SS, ES) для формирования 20-битного адреса (1 МБ). Адрес вычислялся как (сегмент × 16) + смещение. Позже, в защищённом режиме (Protected Mode, начиная с Intel 80286), сегменты стали описываться дескрипторами в глобальной (GDT) или локальной (LDT) таблицах, что обеспечивало защиту (уровни привилегий, кольца защиты) и виртуальную память.

Современное состояние

В 64-битных архитектурах (x86-64, AMD64) сегментная адресация в её классическом виде (сегментные регистры с дескрипторами) была упрощена. В 64-битном режиме (Long Mode) сегменты CS, DS, ES, SS, FS, GS используются в основном для управления привилегиями (кольца 0 и 3) и для доступа к локальным данным (например, через FS и GS в Windows и Linux для thread-local storage). Основной механизм виртуальной памяти в современных ОС — страничная адресация, а сегментация выполняет вспомогательную роль.

Принцип работы

Сегмент и смещение

Каждый сегмент — это непрерывный блок памяти с заданным начальным адресом и длиной (лимитом). Логический адрес (или виртуальный адрес) состоит из двух частей:

Физический адрес вычисляется как базовый адрес сегмента + смещение. Если смещение превышает лимит, возникает исключение (ошибка защиты).

Таблицы дескрипторов

В защищённом режиме x86 используются две таблицы:

  • GDT (Global Descriptor Table) — глобальная таблица дескрипторов, доступная всем задачам. Содержит дескрипторы для ядра, системных сегментов и пользовательских сегментов.
  • LDT (Local Descriptor Table) — локальная таблица дескрипторов, уникальная для каждой задачи (процесса). Позволяет изолировать сегменты разных процессов.

Каждый дескриптор содержит:

  • Базовый адрес (32 бита в защищённом режиме, 64 бита в Long Mode).
  • Лимит (20 бит, с гранулярностью 1 байт или 4 КБ).
  • Тип (код, данные, стек, системный).
  • Уровень привилегий (DPL, 0–3).
  • Флаги (присутствие, доступность, разрешение на запись/чтение).

Сегментные регистры

В x86 процессор имеет шесть сегментных регистров:

  • CS (Code Segment) — указывает на сегмент кода, содержит текущий уровень привилегий (CPL).
  • DS (Data Segment) — сегмент данных по умолчанию.
  • SS (Stack Segment) — сегмент стека.
  • ES, FS, GS — дополнительные сегменты данных (часто используются для специальных целей, например, FS в Windows для thread-local storage).

При каждом обращении к памяти процессор автоматически использует соответствующий сегментный регистр (например, для выборки инструкции — CS, для стека — SS). Программист может явно указать сегментный префикс (например, mov ax, es:[bx]).

Виды сегментной адресации

Реальный режим (Real Mode)

  • Используется в 16-битных процессорах Intel 8086/80286.
  • Адрес: (сегмент × 16) + смещение (20 бит, до 1 МБ).
  • Сегментные регистры содержат непосредственное значение (база), а не дескриптор.
  • Нет защиты: любой сегмент может быть записан или прочитан, нет контроля привилегий.
  • Применялся в DOS и ранних версиях Windows (до Windows 95).

Защищённый режим (Protected Mode)

  • Введён в Intel 80286 (16-битный) и Intel 80386 (32-битный).
  • Адрес: база из дескриптора + смещение (32 бита, до 4 ГБ).
  • Используются GDT/LDT, дескрипторы с защитой (DPL, RPL, CPL).
  • Поддерживается виртуальная память (страничная адресация может быть включена дополнительно).
  • Применялся в Windows NT/2000/XP, Linux (до перехода на 64-битные ядра), OS/2.

64-битный режим (Long Mode)

  • Введён в AMD64 (2003 год) и Intel 64 (EM64T).
  • Сегментная адресация упрощена: сегменты CS, DS, ES, SS, FS, GS используются, но их база и лимит фиксированы (база = 0, лимит = максимальный). Исключение — FS и GS, которые могут иметь ненулевую базу для thread-local storage.
  • Адресация в основном плоская (flat model): все сегменты перекрывают всё адресное пространство (64 бита).
  • Защита на уровне сегментов сохраняется только для CS (привилегии) и для FS/GS (специальные регистры).

Применение

Операционные системы

  • Windows: в 32-битных версиях (NT, 2000, XP) использовалась плоская модель (flat model) с сегментацией для защиты ядра (кольцо 0) и пользователя (кольцо 3). В 64-битных версиях сегменты используются минимально, в основном для thread-local storage (FS) и для управления привилегиями.
  • Linux: в 32-битном режиме Linux использует плоскую модель с четырьмя сегментами (__KERNEL_CS, __KERNEL_DS, __USER_CS, __USER_DS). В 64-битном режиме сегментация ещё более упрощена, но сохраняется для FS (thread-local storage) и для поддержки 32-битных приложений (через CS).
  • OS/2: активно использовала сегментную модель, позволяя программам иметь до 16 000 сегментов.

Программирование

  • Язык ассемблера: в реальном режиме программист явно управляет сегментными регистрами (например, mov ax, @data; mov ds, ax). В защищённом режиме работа с сегментами скрыта за дескрипторами, но программист может задавать их через GDT.
  • Защита памяти: сегменты позволяют изолировать код и данные разных процессов, предотвращая несанкционированный доступ (например, сегмент данных одного процесса не может быть прочитан другим процессом, если не настроен общий сегмент).
  • Thread-local storage (TLS): в современных ОС (Windows, Linux) сегментные регистры FS (x86) или GS (x86-64) используются для хранения указателя на локальные данные потока, что ускоряет доступ к переменным, уникальным для каждого потока.

Преимущества и недостатки

Преимущества

  • Логическая структура: сегменты соответствуют логическим единицам программы (код, данные, стек), что упрощает управление памятью и защиту.
  • Гибкость: сегменты могут иметь произвольный размер, что позволяет эффективно выделять память под структуры данных (например, массивы, строки, таблицы).
  • Защита: сегментные дескрипторы поддерживают уровни привилегий (кольца), что позволяет изолировать ядро ОС от пользовательских процессов и предотвращать ошибки доступа.
  • Совместимость: сегментная адресация в x86 обеспечивает обратную совместимость с 16-битным кодом (реальный режим) и 32-битным кодом (защищённый режим).

Недостатки

  • Фрагментация: сегменты переменной длины могут приводить к внешней фрагментации памяти (как в динамическом выделении), что снижает эффективность использования физической памяти.
  • Сложность управления: работа с сегментами требует от программиста или ОС управления таблицами дескрипторов и обработки исключений (например, при превышении лимита).
  • Производительность: вычисление физического адреса требует дополнительных операций (чтение дескриптора из памяти, проверка лимита, сложение), что может замедлять доступ к памяти по сравнению с плоской адресацией.
  • Ограничение размера: в реальном режиме (16-бит) максимальный размер сегмента — 64 КБ, что ограничивает размер программ и данных. В защищённом режиме (32-бит) лимит может быть до 4 ГБ, но это всё равно меньше, чем 64-битное адресное пространство.

Сравнение со страничной адресацией

ПараметрСегментная адресацияСтраничная адресация
Размер блокаПеременный (от 1 байта до 4 ГБ)Фиксированный (обычно 4 КБ, 2 МБ, 1 ГБ)
Логическая структураСоответствует логическим модулям (код, данные)Не зависит от логики программы
ЗащитаНа уровне сегментов (DPL, кольца)На уровне страниц (биты чтения/записи/исполнения)
ФрагментацияВнешняя (фрагментация памяти)Внутренняя (небольшая потеря из-за фиксированного размера)
УправлениеТребует таблиц дескрипторов (GDT/LDT)Требует таблиц страниц (page tables)
ПрименениеЗащита, изоляция, TLSВиртуальная память, подкачка, большие адресные пространства

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

Интересные факты

  • В процессорах Intel 8086 сегментная адресация позволяла адресовать до 1 МБ памяти, хотя 16-битные регистры могли адресовать только 64 КБ. Это было достигнуто за счёт сдвига сегмента на 4 бита (умножение на 16).
  • В защищённом режиме x86 существует понятие «кольца защиты» (rings): кольцо 0 (самое привилегированное, ядро ОС) и кольцо 3 (наименее привилегированное, пользовательские приложения). Кольца 1 и 2 редко используются, но применялись в OS/2.
  • В 64-битном режиме (Long Mode) сегментные регистры CS, DS, ES, SS, FS, GS по-прежнему существуют, но их база и лимит игнорируются для адресации (кроме FS и GS). Это сделано для упрощения и повышения производительности.
  • Операционная система Multics (1960-е) была одной из первых, где сегментная адресация использовалась для виртуальной памяти и защиты. Она оказала влияние на разработку Unix и Windows.

Источники

  • Intel 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A: System Programming Guide.
  • AMD64 Architecture Programmer’s Manual, Volume 2: System Programming.
  • Таненбаум Э., Бос Х. «Современные операционные системы» (4-е издание), 2015.
  • Patterson D., Hennessy J. «Computer Organization and Design: The Hardware/Software Interface» (5th edition), 2013.
  • Документация Microsoft Windows Internals (7th edition, 2017).