gcc汇编中的本地变量

时间:2012-04-16 15:18:09

标签: gcc assembly compiler-construction

当我用以下代码编译下面的函数时:gcc -S teste.c

void readInput() {
    int buf;
}

teste.S成为:

readInput:
     pushl   %ebp
     movl    %esp, %ebp
     subl    $16, %esp
     leave
     ret

我的疑问是:为什么%esp从16个字节中减去,对于int来说不应该是4个字节?是否有对齐的待办事项?

当我编译它时会发生类似的事情:

void readInput() {
    char buf;
}

,输出与上面相同。

3 个答案:

答案 0 :(得分:0)

基本问题是您没有使用优化,因此它不会尽量减少它分配的空间或它生成的代码。所以这里发生的事情就是为可能需要的东西分配了一堆堆栈空间(展开处理程序,调用setjmp / longjmp / alloca或其他编译器内置函数),但不需要在您的情况下,您从不调用函数或使用可能需要它们的功能。

如果您使用优化(即使只是-O1),此空间也会消失,因为优化程序会看到它未使用。

答案 1 :(得分:0)

缓存命中率

有一些事情正在发生。

  1. 在没有优化的情况下进行编译会留下代码生成器设计的瑕疵。
  2. 无需进一步调用或-g,几乎不需要完整的堆栈帧。
  3. 分配空间时,如果该函数不是叶节点,则可以在缓存行边界或1/2 n 子单元上进行分配。一。我们的想法是未来的调用可能处于循环中,如果新的堆栈帧与两个缓存行重叠,或者 n + 1个缓存行,那么它们将浪费空间并降低命中率。缓存命中率在一段时间内至关重要。出于同样的原因,您有时可能会看到模块和较大的数据结构过度对齐。当然,这与一个合理的目标相冲突,即保持堆栈使用量很小,从而提高缓存效率。

答案 2 :(得分:0)

堆栈保持16字节对齐,可能用于SSE2。 (具有128位= 16 * 8)寄存器。对于64位,这甚至是强制性的。

严格地说,对于使用叶子程序的非SSE,可以省略此要求。