(gdb) disas /m main Dump of assembler code for function main(): 2 { 0x080483f4 <+0>: push %ebp 0x080483f5 <+1>: mov %esp,%ebp 0x080483f7 <+3>: sub $0x10,%esp 3 int a = 1; 0x080483fa <+6>: movl $0x1,-0x4(%ebp) 4 int b = 10; 0x08048401 <+13>: movl $0xa,-0x8(%ebp) 5 int c; 6 c = a + b; 0x08048408 <+20>: mov -0x8(%ebp),%eax 0x0804840b <+23>: mov -0x4(%ebp),%edx 0x0804840e <+26>: lea (%edx,%eax,1),%eax 0x08048411 <+29>: mov %eax,-0xc(%ebp) 7 return 0; 0x08048414 <+32>: mov $0x0,%eax 8 } 0x08048419 <+37>: leave
Обратите внимание на третью инструкцию ассемблера, она выделила 16 байтов вместо ожидаемых 12 байтов . Это почему? Я думал, что 3-я строка выделяет автоматические переменные ...
Даже если я удалил назначение, выделение по-прежнему составляет 16 байт.
Спасибо.
Правка
// no header. nothing int main() { int a = 1; int b = 10; int c; c = a + b; return 0; }
g ++ -g -o demo demo.cpp
Продолжение ... Я прочитал еще пару тем по выравниванию стека (извините, сейчас я изучаю компьютерную архитектуру и класс организации ... так что я вообще с этим не знаком)
Заполнение и выравнивание распределения стека
Я полагаю, это установка компилятора. Поэтому по умолчанию минимальный размер составляет 16 байт.
Если бы у нас было
int a = 1; int b = 10; int c = 10; int d = 10; // -- int e = 10;
До int d, у нас было бы ровно 16 байт, а выделение по-прежнему равно 0x10. Но когда мы даем еще одно восхищение, int e = 10, esp теперь выделяется 32 байта (0x20).
Это показывает мне, что esp, указатель стека, используется только для автоматических переменных.
Follow-up 2
Стек вызовов и кадр стека
Каждый кадр стека
Место для хранения всех автоматических переменных для вновь вызванной функции. Номер строки вызывающей функции, к которой нужно вернуться, когда вызываемая функция вернется. Аргументы или параметры вызываемой функции.
Но после того, как мы выделили int a через int d, нам уже потребовалось 16 байт. Main не имеет параметров функции, так что это ноль.Но линия для возврата, куда делась эта информация?