stringtranslate.com

Сегмент данных

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

Сегмент данных доступен для чтения/записи, поскольку значения переменных могут быть изменены во время выполнения. В этом отличие от сегмента данных, доступного только для чтения (сегмент rodata или.rodata), который содержит статические константы, а не переменные; он также отличается отсегмента кода, также известного как текстовый сегмент, который на многих архитектурах доступен только для чтения. Неинициализированные данные, как переменные, так и константы, вместо этого находятся всегменте BSS.

Исторически, чтобы иметь возможность поддерживать адресные пространства памяти, превышающие собственный размер регистра внутреннего адреса, ранние процессоры реализовывали систему сегментации, посредством которой они хранили небольшой набор индексов для использования в качестве смещений в определенных областях. Семейство процессоров Intel 8086 имело четыре сегмента: сегмент кода, сегмент данных, сегмент стека и дополнительный сегмент. Каждый сегмент помещался в определенное место в памяти выполняемым программным обеспечением, и все инструкции, которые работали с данными в этих сегментах, выполнялись относительно начала этого сегмента. Это позволило 16-битному адресному регистру, который обычно имел доступ к 64 КБ памяти, получить доступ к 1 МБ памяти.

Это сегментирование пространства памяти на отдельные блоки с конкретными задачами, перенесенное в языки программирования того времени, и эта концепция до сих пор широко используется в современных языках программирования.

Память программ

Память компьютерных программ можно условно разделить на две части: только для чтения и для чтения/записи. Это различие возникло из-за того, что ранние системы хранили свою основную программу в постоянной памяти, такой как Mask ROM , EPROM , PROM или EEPROM . Поскольку системы становились более сложными и программы загружались с других носителей в ОЗУ вместо выполнения из ПЗУ, идея о том, что некоторые части памяти программы не следует изменять, сохранялась. Они стали сегментами .text и .rodata программы, а оставшаяся часть, которую можно было записать, была разделена на ряд других сегментов для конкретных задач.

Код

Сегмент кода , также известный как текстовый сегмент , содержит исполняемый код, обычно доступен только для чтения и имеет фиксированный размер.

Данные

Здесь показано типичное расположение программной памяти простого компьютера с текстом, различными данными, а также секциями стека и кучи.

Сегмент данных содержит инициализированные статические переменные, т.е. глобальные переменные и локальные статические переменные, которые имеют определенное значение и могут быть изменены. Примеры в C включают:

интервал я = 3 ; char a [] = "Привет, мир" ; статический int b = 2023 ; // Инициализированная статическая глобальная переменная void foo ( void ) { static int c = 2023 ; // Инициализированная статическая локальная переменная }                    

БСС

Сегмент BSS содержит неинициализированные статические данные, как переменные, так и константы, т.е. глобальные переменные и локальные статические переменные, которые инициализируются нулем или не имеют явной инициализации в исходном коде. Примеры в C включают:

статический int я ; статический символ а [ 12 ];    

Куча

Сегмент кучи содержит динамически выделяемую память, обычно начинается в конце сегмента BSS и оттуда увеличивается до более крупных адресов. Он управляется с помощью malloc , calloc, realloc и free, которые могут использовать системные вызовы brk и sbrk для регулировки его размера (обратите внимание, что использование brk/sbrk и одного сегмента кучи не требуется для выполнения контракта malloc/ calloc/realloc/free; они также могут быть реализованы с использованием mmap /munmap для резервирования/отменения резервирования потенциально несмежных областей виртуальной памяти в виртуальном адресном пространстве процесса ). Сегмент кучи используется всеми потоками, общими библиотеками и динамически загружаемыми модулями в процессе.

Куча

Сегмент стека содержит стек вызовов , структуру LIFO , обычно расположенную в верхних частях памяти. Регистр «указатель стека» отслеживает вершину стека; оно корректируется каждый раз, когда значение «помещается» в стек. Набор значений, передаваемых для одного вызова функции, называется «фреймом стека». Кадр стека состоит как минимум из адреса возврата. Автоматические переменные также размещаются в стеке.

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

Интерпретируемые языки

Некоторые интерпретируемые языки предлагают аналогичные возможности для сегмента данных, в частности Perl [1] и Ruby . [2] В этих языках включение строки __DATA__(Perl) или __END__(Ruby, старый Perl) отмечает конец сегмента кода и начало сегмента данных. Выполняется только содержимое до этой строки, а содержимое исходного файла после этой строки доступно как файловый объект: PACKAGE::DATAв Perl (например, main::DATA) и DATAв Ruby. Это можно рассматривать как форму здесь документа (файловый литерал).

Смотрите также

Рекомендации

  1. ^ perldata: специальные литералы
  2. ^ Руби: Объект: __END__

Внешние ссылки