Почему тип 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 хранит инициализированные.

  1. Зачем int занимает 8 байтов в BSS? sizeof(x) в моем коде показывает, что int на самом деле занимает 4 байта.
  2. 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).

Другие вопросы по тегам