为什么gcc 4.x默认在调用方法时为linux上的堆栈保留8个字节?

作为asm的初学者,我正在检查gcc -S生成的asm代码来学习。

为什么gcc 4.x默认为调用方法时保留8个字节的堆

func18是空函数,没有返回没有参数没有本地variables定义。 我不知道为什么8字节保留在这里(没有任何论坛/网站提到的理由,脂肪酶似乎是理所当然的)是%ebp只是推? 还是返回types? 很多thx!

.globl _func18 _func18: pushl %ebp movl %esp, %ebp subl $8, %esp .text 

Solutions Collecting From Web of "为什么gcc 4.x默认在调用方法时为linux上的堆栈保留8个字节?"

某些指令要求将某些数据类型对齐到16字节的边界(特别是SSE数据类型__m128)。 为了满足这个要求,gcc确保堆栈最初是16字节对齐的,并且以16个字节的倍数分配堆栈空间。 如果只需要推送4字节的返回地址和4字节的帧指针,则需要8个附加字节来保持堆栈与16字节的边界对齐。 但是,如果gcc确定不需要附加对齐(即不使用奇特的数据类型,并且没有调用外部函数),则可能会省略任何用于对齐堆栈的附加指令。 确定这一点所需的分析可能需要执行某些优化。

另请参阅gcc文档中的选项-mpreferred-stack-boundary = num

正如上面提到的理查德,这都是因为优化,下面显示。 但我仍然不知道为什么8个字节保留是优化?

原来的c

 void func18() {} int main() {return 0;} 

编译没有指定优化标志

  .text .globl _func18 _func18: pushl %ebp movl %esp, %ebp subl $8, %esp leave ret .globl _main _main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $0, %eax leave ret .subsections_via_symbols 

与-Os优化标志,没有更多的堆栈保留

  .text .globl _func18 _func18: pushl %ebp movl %esp, %ebp leave ret .globl _main _main: pushl %ebp xorl %eax, %eax movl %esp, %ebp leave ret .subsections_via_symbols 

简单的方法来找出:你有空函数调用另一个函数与一个参数。 如果参数直接存储到堆栈(不推),那么这就是多余的空间。