Почему тип int занимает 8 байтов в разделе BSS, но 4 байта в разделе DATA
Я пытаюсь узнать структуру исполняемых файлов программы C. Моя среда - GCC и 64-битный процессор Intel.
Рассмотрим следующий код C a.cc
,
#include <cstdlib>
#include <cstdio>
int x;
int main(){
printf("%d\n", sizeof(x));
return 10;
}
size -o a
шоу
text data bss dec hex filename
1134 552 8 1694 69e a
После того, как я добавил еще одну инициализированную глобальную переменную y.
int y=10;
size a
показывает (где a
имя исполняемого файла из a.cc)
text data bss dec hex filename
1134 556 12 1702 6a6 a
Как мы знаем, BSS
раздел хранит размер неинициализированных глобальных переменных и DATA
хранит инициализированные.
- Зачем
int
занимает 8 байтов в BSS?sizeof(x)
в моем коде показывает, чтоint
на самом деле занимает 4 байта. -
int y=10
добавил 4 байта к данным, что имеет смысл, так какint
должно занять 4 байта. Но почему он добавляет 4 байта в BSS?
Разница между двумя size
команды остаются прежними после удаления двух строк #include ...
,
Обновление: я думаю, что мое понимание BSS неверно. Может не хранить неинициализированные глобальные переменные. Как гласит Википедия: "Размер, который BSS потребует во время выполнения, записан в объектном файле, но BSS (в отличие от сегмента данных) не занимает фактического пространства в объектном файле". Например, даже однострочный код C int main(){}
имеет bss 8
,
8 или 16 BSS происходит от alignment
?
1 ответ
Это не так, он занимает 4 байта независимо от того, в каком сегменте он находится. Вы можете использовать nm
инструмент (из пакета GNU binutils) с -S
аргумент, чтобы получить имена и размеры всех символов в объектном файле. Вы, вероятно, видите вторичные эффекты компилятора, включающие или не включающие некоторые другие символы по тем или иным причинам.
Например:
$ cat a1.c
int x;
$ cat a2.c
int x = 1;
$ gcc -c a1.c a2.c
$ nm -S a1.o a2.o
a1.o:
0000000000000004 0000000000000004 C x
a2.o:
0000000000000000 0000000000000004 D x
Один объектный файл имеет 4-байтовый объект с именем x
в сегменте неинициализированных данных (C
), в то время как другой объектный файл имеет 4-байтовый объект с именем x
в инициализированном сегменте данных (D
).