По сути, в программах на C, предназначенных для работы с ELF (исполняемым и связываемым форматом), таких как программы, основанные на linux, создается стандартная схема памяти. Подобные макеты, вероятно, существуют для других архитектур, но я не знаю достаточно, чтобы рассказать вам больше о них.
Макет:
Существуют некоторые разделы глобальных данных, которые инициализируются в памяти по низким адресам памяти (например, разделы для исполняемого в настоящее время кода, глобальные данные и любые строки, созданные с помощью "..."
внутри вашего кода C).
Ниже есть куча открытой памяти, которую можно использовать. Размер этой кучи автоматически увеличивается по мере обращения к malloc и свободного перемещения так называемого «разрыва программы» на более высокие адреса в памяти.
Начиная с высокого адреса в памяти, стек увеличивается в сторону более низких адресов. Стек содержит память для любых локально распределенных переменных, таких как те, что находятся вверху функций или в области ({ ... }
).
Подробнее:
Хорошее описание работающей программы ELF здесь и более подробную информацию о самом формате можно найти в статье Википедии . Если вам нужен пример того, как компилятор выполняет преобразование кода C в сборку, вы можете взглянуть на GCC, в его Internals Manual есть некоторые интересные вещи; Наиболее значимыми являются, вероятно, разделы в главе 17, особенно 17.10, 17.19 и 17.21. Наконец, Intel имеет много информации о разметке памяти в Руководстве разработчика программного обеспечения IA-32 Architectures. Он описывает, как процессоры Intel обрабатывают сегментацию памяти и создают стеки и тому подобное. Там нет никаких подробностей об ELF, но можно увидеть, где они совпадают. Наиболее полезными являются, вероятно, раздел 3.3 тома 1: Базовая архитектура и глава 3 тома 3А: Руководство по системному программированию, часть 1.
Надеюсь, это поможет любому окунуться во внутренности запуска программ на С, удачи.