Я пытаюсь получить более глубокое понимание того, как компиляторы генерируют машинный код, а точнее, как GCC имеет дело со стеком. При этом я пишу простые программы на С, компилируя их в сборку и изо всех сил пытаюсь понять результат. Здесь простую программу и выходные данные, которые она генерирует:
asmtest.c
:
void main() {
char buffer[5];
}
asmtest.s
:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
leave
ret
Что меня озадачивает, так почему для стека выделяется 24 байта. Я знаю, что из-за того, как процессор обращается к памяти, стек должен быть распределен с шагом 4, но если это так, мы должны только перемещать указатель стека на 8 байтов, а не 24. Для справки буфер 17 байт вырабатывает указатель стека, перемещаемый 40 байтами, и никакой буфер вообще не перемещает указатель стека 8. Буфер между 1 и 16 байтами включительно перемещает ESP
24 байта.
Теперь, полагая, что 8 байтов - необходимая константа (для чего это необходимо?), это означает, что мы выделяем куски по 16 байт. Почему компилятор должен быть таким образом совмещен? Я использую процессор x86_64, но даже для 64-битного слова требуется только выравнивание по 8 байт. Почему расхождение?
Для справки я компилирую это на Mac, работающем 10.5 с gcc 4.0.1, и оптимизация не включена.