как насчет .bss раздел не инициализируется нулями - PullRequest
4 голосов
/ 20 августа 2010

как мы знаем .bss содержит неинициализированные переменные.если в коде c, программист инициализирует переменные перед их использованием.тогда .bss не обязательно должен быть нулем перед выполнением кода C.

Я прав?

Спасибо

Ответы [ 4 ]

13 голосов
/ 20 августа 2010

В коде C любая переменная со статической продолжительностью хранения определяется как инициализируемая в 0 спецификацией (Раздел 6.7.8 Инициализация, параграф 10):

Если объект со статической продолжительностью хранения не инициализирован явно, то:

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

Некоторые загрузчики программ заполняют весь раздел нулями для начала, а другие заполняют его «по требованию» в качестве улучшения производительности. Таким образом, хотя вы технически правы, что раздел .bss не может на самом деле содержать все нули, когда код C начинает выполняться, он логически делает. В любом случае, если у вас есть стандартный совместимый набор инструментов, вы можете думать, что он равен нулю.

Любые переменные, которые инициализируются ненулевыми значениями, никогда не попадут в раздел .bss; они обрабатываются в секциях .data или .rodata, в зависимости от их конкретных характеристик.

5 голосов
/ 20 августа 2010

В спецификации ELF сказано:

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

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

1 голос
/ 20 августа 2010

Это зависит от того, где находится переменная в коде.Например, если вы говорите о локальной переменной в main () или любой другой функции, то переменные помещаются в стек (если вы не используете другие модифицирующие ключевые слова).Если ваша переменная глобальная И неинициализированная, она должна храниться в .bss.Обратите внимание, что оптимизация компилятора и так далее может немного изменить ситуацию.Если вы хотите знать наверняка, используйте readelf для изучения ELF-файла в Linux.

0 голосов
/ 20 августа 2010

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

...