.раздел данных в сборке x86

# #assembly #x86 #masm

Вопрос:

Я пытаюсь выучить язык ассемблера и не смог понять концепцию объявления глобальных переменных с помощью .раздел данных .Когда вы объявляете переменную в разделе .data , ассемблер/компоновщик сопоставляет ее с ячейкой памяти. Но как он узнает о свободной памяти, доступной при компиляции исходного кода. Если выделение памяти выполняется во время выполнения ,то как программа узнает, где выделять память, поскольку мы не делаем этого в коде.

Комментарии:

1. Метаданные в исполняемом файле сообщают программному загрузчику ядра, сколько байтов данных нужно отобразить в память. Для такой операционной системы, как Windows, которая использует виртуальную память, чтобы предоставить каждому процессу собственное адресное пространство, это очень просто: компоновщик знает, что доступно все адресное пространство 4 Гб (или, по крайней мере, его 2 Гб с 32-разрядными ядрами, резервирующими верхнюю часть).

Ответ №1:

Но как он узнает о свободной памяти, доступной при компиляции исходного кода.

При компиляции; он использует очень простой распределитель для создания пространства для фрагментов кода и данных в разделах, где этот распределитель может быть таким же простым, как « offset = section.size; section.size = object.size «. Позже (при связывании), когда известны окончательные размеры разделов (и известен адрес для начала каждого раздела), он возвращается и преобразует эти смещения в адреса, добавляя «адрес для начала раздела» к каждому «смещению в разделе».

Затем сведения о разделах (их адрес в памяти, размер, атрибуты, где они находятся в исполняемом файле) сохраняются в заголовке исполняемого файла.

Когда исполняемый файл загружен, ОС использует заголовок исполняемого файла, чтобы выяснить, какие части файла загружаются/сопоставляются где. Обычно ОС (или язык программирования библиотеки) будет также отслеживать, какие участки виртуального адресного пространства используются для того, что; так, что если/когда программа выделяет больше виртуального адресного пространства (использование функций, как VirtualAlloc() в Windows или mmap() в Unix клонов), которые он может выделить виртуальное пространство, которое уже не используется (по секциям, и т. д.).

Наконец, когда программа начинает работать (возможно, в «запуска по умолчанию код», что компоновщик включены для вас) это, вероятно, выделить виртуальное пространство для программы кучи, а затем использовать это виртуальное пространство для настройки динамического управления памятью (например, malloc() или new и все, что имеет смысл для языка и его библиотек).

Примечание 1: Компиляция и компоновка не так просты (например, распределителю, используемому для создания пространства в разделах, тоже придется беспокоиться о таких вещах, как выравнивание).

Примечание 2: Загрузчики исполняемых файлов не так просты (например, они также загружают/сопоставляют общие библиотеки и выполняют динамическое связывание).

Примечание 3: Большинство современных систем используют «рандомизацию компоновки адресного пространства» (в попытке повысить безопасность), поэтому конечные адреса (используемые кодом, данными) могут определяться (по смещениям в разделах) исполняемым загрузчиком (как часть динамической компоновки) и не полностью определяются самим компоновщиком.