我一直在努力更深入地了解编译器是如何生成机器代码的,更具体地说,是GCC是如何处理堆栈的.在这样做的过程中,我一直在编写简单的C程序,将它们编译成汇编语言,并尽力理解结果.下面是一个简单的程序及其生成的输出:
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字节对齐.为什么会有这样的差异呢?
作为参考,我在运行10.5、GCC4.0.1且未启用优化的Mac上编译了这篇文章.