为什么GCC没有优化掉函数序言和结语(push ebp; mov ebp,esp; ...; pop ebp)

时间:2014-02-07 05:44:56

标签: c gcc assembly compiler-optimization calling-convention

当编译一个甚至不改变ebp寄存器的简单函数时,GCC仍会在函数开头保存该值,然后在结束时恢复相同的值:

#add.c
int add( int a, int b )
{
  return ( a + b );
}

gcc -c -S -m32 -O3 add.c -o add.S

#add.S
    .file   "add.c"
    .text
    .p2align 4,,15
.globl add
    .type   add, @function
add:
    pushl   %ebp
    movl    %esp, %ebp
    movl    12(%ebp), %eax
    addl    8(%ebp), %eax
    popl    %ebp
    ret
    .size   add, .-add
    .ident  "GCC: (GNU) 4.4.6"
    .section        .note.GNU-stack,"",@progbits

使ebp保持不变似乎是一个简单的优化,计算相对于esp的偏移并保存3条指令。

为什么海湾合作委员会不这样做?

谢谢,

安德鲁

1 个答案:

答案 0 :(得分:4)

调试器和堆栈行走器等工具曾经期望代码具有构造帧指针的序言,并且无法理解没有它的代码。随着时间的推移,限制已被删除。

编译器本身在没有帧指针的情况下生成代码没有任何困难,您可以要求使用-fomit-frame-pointer删除它。我相信最近版本的gcc(~4.8)和x86-64上的gcc默认省略了帧指针。