Почему этот исходный код выделил 16 байт?

(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 не имеет параметров функции, так что это ноль.Но линия для возврата, куда делась эта информация?

6
задан Community 23 May 2017 в 11:47
поделиться