Инициализация переменных зависит от типа переменных.Глобальные или статические переменные инициализируются во время компиляции, тогда как автоматические переменные полностью управляются во время выполнения.
Глобальные переменные
Во время компиляции,значение всех глобальных переменных известно.Эти значения записываются компилятором в определенные разделы объектного файла.
Во время компоновки все объектные файлы собираются и для каждой переменной определяются места в памяти.Это позволяет узнать адрес каждой переменной в случае, если один из этих адресов назначен другой переменной.
В результате создается исполняемый файл, содержащий описание содержимого каждого раздела (текст, данные, родата)., так далее).В разделе data или rodata записываются значения всех инициализированных глобальных переменных.
во время выполнения, загрузчик считывает описание различных разделов и запрашивает память операционной системы.Затем он скопирует содержимое всех разделов в соответствующие ячейки памяти.
Таким образом, переменная инициализируется значением, определенным во время компиляции или компоновки.
Единственное исключение - переменные, которые инициализируются с нуля (или не инициализирован).Они расположены в специальном разделе (часто называемом bss).Чтобы уменьшить размер исполняемых файлов, эти нулевые значения не записываются в исполняемый файл.Вместо этого, перед выполнением main()
, во время выполнения процедура memset обнулит все содержимое секции bss.
Автоматические переменные
Процедура совершенно иная.Никто не знает, где находятся эти переменные до запуска программы, и единственный способ - это вычислить их значения с помощью машинных инструкций.
Таким образом, компилятор сначала определяет, будут ли эти переменные находиться в регистре или памяти, и когдаПри входе в функцию первыми инструкциями будет резервирование стекового пространства для локальных переменных и инициализация их значений.Это делается с помощью обычных машинных инструкций.
В случае, если значением является адрес другой переменной (скажем, y = & x),
*, если x является локальной (автоматической) переменной, адрес будетвычисляется путем записи в y
суммы содержимого регистра указателя стека и заданного смещения, определенного компилятором
*, если x является глобальной или статической переменной, во время соединения, как только адреса глобальных переменныхизвестно, что компоновщик изменяет инструкции, сгенерированные компилятором, чтобы записать правильный адрес в регистр или место в стеке, используемое для представления y
.