сегмент bss в C

в одном из ответов на вопрос "относительно сегмента bss и сегмента данных в Unix", Я вижу объяснение на bss следующим образом:

Bss особенный: .объекты bss не занимают места в объектном файле, и, группируя все символы, которые не являются специально intialized вместе, они могут быть легко обнулены сразу.

но когда я использую размер в объектном файле, сгенерированном из кода:

#include <stdio.h>
int uninit_global_var;
int init_global_var=5;

int main()
{
   int local_var;
   return 0;
}

I следующие

text    data      bss    dec     hex filename
1231     280      12    1523     5f3 a.out

и см. Рост bss на основе неинициализированных членов данных с глобальной областью. Так может ли кто-нибудь оправдать упомянутое утверждение?

4 ответов


если вы удалите stdio.h ваш результат, вероятно, будет более значимым. Давайте проигнорируем эту библиотеку, поскольку она содержит внутренние переменные.

в вашем конкретном случае, происходит следующее:

int uninit_global_var;

так как это переменная, выделенная в объем файла в has статическая продолжительность хранения, как и любая переменная, объявленная как static. Стандарт C требует, чтобы если переменная со статической длительностью хранения не инициализируется явно программист, как и в этом случае, должен быть установлен на ноль, прежде чем программа запустится. Все такие переменные помещаются в .bss сегменте.

int init_global_var=5;

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


Я не знаю точного ответа, но мое предположение такое:

размер сегмента bss находится в объектном файле и отображается размером -> он должен быть выделен, в конце концов.

но объектный файл не будет расти, когда сегмент BSS растет.


a.out вероятно, это не объектный файл, это, вероятно, исполняемый файл ELF. Перемещаемых объектов, как правило, называют имя.o, являются промежуточными файлами до возникновения ссылки. См. параметр-c для gcc.


сегмент bss растет, но вам не нужен этот сегмент в вашем двоичном файле (см. objcopy).

поэтому, в конце концов, если вы поместите этот код в какой-то ПЗУ, он не займет там места, но потребует места в ОЗУ (и кода для инициализации его до 0).