Сегмент данных
В вычислениях сегмент данных (часто обозначаемый .data ) — это часть объектного файла или соответствующего адресного пространства программы, которая содержит инициализированные статические переменные , то есть глобальные переменные и статические локальные переменные . Размер этого сегмента определяется размером значений в исходном коде программы и не меняется во время выполнения .
Сегмент данных доступен для чтения/записи, поскольку значения переменных могут быть изменены во время выполнения. В этом отличие от сегмента данных, доступного только для чтения ( rodata сегмент или .rodata ), который содержит статические константы, а не переменные; он также отличается от сегмента кода , также известного как текстовый сегмент, который на многих архитектурах доступен только для чтения. Неинициализированные данные, как переменные, так и константы, вместо этого находятся в сегменте BSS .
Исторически, чтобы иметь возможность поддерживать адресные пространства памяти, превышающие собственный размер внутреннего адресного регистра, ранние процессоры реализовывали систему сегментации, посредством которой они хранили небольшой набор индексов для использования в качестве смещений в определенных областях. Семейство процессоров Intel 8086 имело четыре сегмента: сегмент кода, сегмент данных, сегмент стека и дополнительный сегмент. Каждый сегмент помещался в определенное место в памяти выполняемым программным обеспечением, и все инструкции, которые работали с данными в этих сегментах, выполнялись относительно начала этого сегмента. Это позволило 16-битному адресному регистру, который обычно имел доступ к 64 КБ памяти, получить доступ к 1 МБ памяти.
Это сегментирование пространства памяти на отдельные блоки с конкретными задачами, перенесенное в языки программирования того времени, и эта концепция до сих пор широко используется в современных языках программирования.
Память программ
[ редактировать ]Память компьютерных программ можно условно разделить на две части: только для чтения и для чтения/записи. Это различие возникло из-за того, что ранние системы хранили свою основную программу в постоянной памяти, такой как Mask ROM , EPROM , PROM или EEPROM . Поскольку системы становились более сложными и программы загружались с других носителей в ОЗУ вместо выполнения из ПЗУ, идея о том, что некоторые части памяти программы не следует изменять, сохранялась. Они стали сегментами .text и .rodata программы, а оставшаяся часть, которую можно было записать, была разделена на ряд других сегментов для конкретных задач.
Код
[ редактировать ]Сегмент кода , также известный как текстовый сегмент , содержит исполняемый код и обычно доступен только для чтения и имеет фиксированный размер.
Данные
[ редактировать ]Сегмент данных содержит инициализированные статические переменные, т.е. глобальные переменные и локальные статические переменные, которые имеют определенное значение и могут быть изменены. Примеры в C включают:
int i = 3;
char a[] = "Hello World";
static int b = 2023; // Initialized static global variable
void foo (void) {
static int c = 2023; // Initialized static local variable
}
БСС
[ редактировать ]Сегмент BSS содержит неинициализированные статические данные, как переменные, так и константы, т.е. глобальные переменные и локальные статические переменные, которые инициализируются нулем или не имеют явной инициализации в исходном коде. Примеры в C включают:
static int i;
static char a[12];
Куча
[ редактировать ]Сегмент кучи содержит динамически выделяемую память, обычно начинается в конце сегмента BSS и оттуда увеличивается до более крупных адресов. Он управляется с помощью malloc , calloc, realloc и free, которые могут использовать системные вызовы brk и sbrk для регулировки его размера (обратите внимание, что использование brk/sbrk и одного сегмента кучи не требуется для выполнения контракта malloc/ calloc/realloc/free; они также могут быть реализованы с использованием mmap /munmap для резервирования/отменения резервирования потенциально несмежных областей виртуальной памяти в виртуальном адресном пространстве процесса ). Сегмент кучи используется всеми потоками, общими библиотеками и динамически загружаемыми модулями в процессе.
Куча
[ редактировать ]Сегмент стека содержит стек вызовов , структуру LIFO , обычно расположенную в верхних частях памяти. Регистр «указатель стека» отслеживает вершину стека; оно корректируется каждый раз, когда значение «помещается» в стек. Набор значений, передаваемых для одного вызова функции, называется «фреймом стека». Кадр стека состоит как минимум из адреса возврата. Автоматические переменные также размещаются в стеке.
Сегмент стека традиционно примыкал к сегменту кучи и они росли навстречу друг другу; когда указатель стека встретил указатель кучи, свободная память была исчерпана. Благодаря большим адресным пространствам и технологиям виртуальной памяти они, как правило, размещаются более свободно, но их рост по-прежнему обычно происходит в сходящемся направлении. В стандартной архитектуре ПК x86 стек растет по направлению к нулевому адресу, а это означает, что более поздние элементы, расположенные глубже в цепочке вызовов, находятся по численно меньшим адресам и ближе к куче. В некоторых других архитектурах он растет в противоположном направлении.
Интерпретируемые языки
[ редактировать ]Некоторые интерпретируемые языки предлагают аналогичные возможности для сегмента данных, особенно Perl. [1] и Руби . [2] В этих языках, включая строку __DATA__
(Перл) или __END__
(Ruby, старый Perl) отмечает конец сегмента кода и начало сегмента данных. Выполняется только содержимое до этой строки, а содержимое исходного файла после этой строки доступно как файловый объект: PACKAGE::DATA
в Perl (например, main::DATA
) и DATA
в Руби. Это можно рассматривать как форму здесь документа (файловый литерал).
См. также
[ редактировать ]- Сегментация (память)
- Ошибка сегментации
- Линкер (вычисления)
- Сегмент кода
- .bss
- Неинициализированная переменная
- Стек (абстрактный тип данных)
- Блок управления процессом
Ссылки
[ редактировать ]- ^ perldata: специальные литералы
- ^ Руби: Объект: __END__
Внешние ссылки
[ редактировать ]- «С-запуск» . www.braregnu.org .
- «mem_sequence.c — последовательно перечисляет области памяти в процессе» . Архивировано из оригинала 2 февраля 2009 г.
- ван дер Линден, Питер (1997). Экспертное программирование на C: секреты Deep C (PDF) . Прентис Холл. стр. 119 и далее.