Это очень сильно зависит от компилятора, но логически хранилище назначается, как только объявлена переменная.
Рассмотрим этот упрощенный пример C ++:
// junk.c++
int addtwo(int a)
{
int x = 2;
return a + x;
}
Когда GCC компилирует это, генерируется следующий код (; комментарии мои ):
.file "junk.c++"
.text
.globl _Z6addtwoi
.type _Z6addtwoi, @function
_Z6addtwoi:
.LFB2:
pushl %ebp ;store the old stack frame (caller's parameters and locals)
.LCFI0:
movl %esp, %ebp ;set up the base pointer for our parameters and locals
.LCFI1:
subl $16, %esp ;leave room for local variables on the stack
.LCFI2:
movl $2, -4(%ebp) ;store the 2 in "x" (-4 offset from the base pointer)
movl -4(%ebp), %edx ;put "x" into the DX register
movl 8(%ebp), %eax ;put "a" (+8 offset from base pointer) into AX register
addl %edx, %eax ;add the two together, storing the results in AX
leave ;tear down the stack frame, no more locals or parameters
ret ;exit the function, result is returned in AX by convention
.LFE2:
.size _Z6addtwoi, .-_Z6addtwoi
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",@progbits
Все, что находится между _Z6addtwoi и .LCFI2, является стандартным кодом, используемым для установки стекового фрейма (надежно храните переменные предыдущей функции и т. Д.). Последний «subl $ 16,% esp» - это распределение локальной переменной x.
.LCFI2 - это первый бит введенного вами кода. «movl $ 2, -4 (% ebp)» помещает значение 2 в переменную. (Инициализация, другими словами.) Теперь ваше пространство выделено И инициализировано. После этого он загружает значение в регистр EDX и затем перемещает ваш параметр, найденный в «8 (% ebp)», в другой регистр EAX. Затем они складывают их вместе, оставляя результат в EAX. Теперь это конец любого кода, который вы на самом деле набрали. Остальное опять просто шаблон. Поскольку GCC требует, чтобы целые числа возвращались в EAX, для возвращаемого значения не требуется никакой работы. Инструкция «exit» разрушает кадр стека, а инструкция «ret» возвращает управление обратно вызывающей стороне.
TL; DR сводка: вы можете думать о том, что ваше пространство выделено самой первой строкой исполняемого кода в вашем блоке (в паре {}).
Я подумал, что немного исправлю это с помощью пояснительных комментариев, поскольку это выбранный ответ.