У меня возникла небольшая проблема при обучении. Я знаю, что неинициализированные глобальные переменные в C назначаются секции .bss в исполняемом ELF-файле. Но что с ними происходит, когда я начинаю их использовать? Т.е. им место в куче или еще где?

Я попытался выяснить это, напечатав адрес (все еще неинициализированной) глобальной переменной с помощью

printf("%x",&glbl);

Которые всегда возвращают одно и то же значение 0x80495bc ... Почему?

8
Patrick 11 Авг 2009 в 17:27

4 ответа

Лучший ответ

Когда ОС загружает вашу программу, она выделяет достаточно памяти из адресного пространства вашей программы для хранения всего в разделе .bss и обнуляет всю эту память. Когда вы назначаете, читаете или берете адрес переменной, вы манипулируете той памятью, которая была выделена для обеспечения хранилища для раздела .bss.

8
Nick Meyer 11 Авг 2009 в 13:32

Этому разделу BSS предоставляется блок памяти в адресном пространстве процесса, как и разделам кода и стека (и любому другому ELF). Попав туда, они никуда не уходят . Загрузчик упорядочивает вещи, затем вызывает точку входа в процесс.

1
paxdiablo 11 Авг 2009 в 13:33

BSS - это заполнитель, определенный в вашем исполняемом (или ELF) формате. Таким образом, он не занимает дисковое пространство, а только указывает, какая область памяти должна быть выделена компоновщиком или загрузчиком.

Точная операция зависит от операционной системы. Поскольку вы ссылаетесь на ELF, я предполагаю, что он предназначен для использования во встроенной системе. Если вы выполняете сборку для ROMmable кода, ваш cmd-файл компоновщика сопоставляет BSS с областью статического адреса.

Если вы выполняете сборку для операционной системы (например, Linux), загрузчик из операционной системы выполнит этап перемещения, в котором он сопоставляет все местоположения, отмеченные как относительные в формате Excutable, с физическими или логическими местоположениями в памяти.

Поскольку вы упоминаете, что всегда видите одно и то же значение, это указывает на то, что процесс повторяется для вашей системы. Ожидайте увидеть изменения при изменении файлов компоновщика (т. Е. Областей адресов), порядка связывания (т. Е. Модулям будет назначено пространство в другом порядке) или операционной системы.

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

1
Adriaan 11 Авг 2009 в 13:31

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

2
Arkaitz Jimenez 11 Авг 2009 в 13:30