【问题标题】:Why is my stack pointer only incrementing in multiples of 16?为什么我的堆栈指针仅以 16 的倍数递增?
【发布时间】:2011-07-26 15:30:37
【问题描述】:

使用以下 C 代码

void func() {
  int a=1,b=2,c=3;
}

使用gcc -S -O -o- myfile.c编译得到输出

    .file   "myfile.c"
    .intel_syntax noprefix
    .text
.globl func
    .type   func, @function
func:
    push    ebp
    mov ebp, esp
    sub esp, 16
    mov DWORD PTR [ebp-4], 1
    mov DWORD PTR [ebp-8], 2
    mov DWORD PTR [ebp-12], 3
    mov DWORD PTR [ebp-16], 4
    mov DWORD PTR [ebp-20], 5
    leave
    ret
    .size   func, .-func
    .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
    .section    .note.GNU-stack,"",@progbits

这里我希望func: 之后的第三行是sub esp,12 而不是sub esp,16。我在函数中使用了不同数量的自动变量,发现它以 16 个字节的增量增长。为什么会这样?这发生在所有平台上,还是特定于平台?

我目前正在运行带有 OSX 的 Intel Mac,使用 GCC 通过 Ubuntu(32 位)VirtualBox 来宾进行编译。

【问题讨论】:

    标签: assembly x86


    【解决方案1】:

    来自GCC man page,(我的粗体强调):

    -mpreferred-stack-boundary=num

    尝试保持堆栈边界与 2 提升到 num 字节边界对齐。如果未指定-mpreferred-stack-boundary,默认为 4(16 字节或 128 位)。

    【讨论】:

    • 编译器这样做的原因是某些访问内存位置未对齐的指令会降低性能。
    • 谢谢,在这个答案和 vidstige 的评论之间,我有我需要的信息 :)
    • @vidstige @Martin: 否则它们会崩溃,即使在 x86 上也是如此(参见 movaps,例如)。
    【解决方案2】:

    这是很奇怪的输出。

    你确定c文件不是:

    void func() {
      int a=1,b=2,c=3,d=4,e=5;
    }
    

    ?

    否则为什么会出现线条

    mov DWORD PTR [ebp-16], 4
    mov DWORD PTR [ebp-20], 5
    

    【讨论】:

    • 我同意你的观点,但这不应该是一个答案。这实际上是 OP 的问题。
    【解决方案3】:

    x86_64 ABI 要求堆栈为 16 字节对齐

    Stack allocation, padding, and alignment

    对于 32 位 OS X,由于 SSE 和其他一些原因,它会这样做

    Why does the Mac ABI require 16-byte stack alignment for x86-32?

    【讨论】:

      猜你喜欢
      • 2019-10-15
      • 1970-01-01
      • 2019-11-23
      • 2010-12-19
      • 2019-08-27
      • 1970-01-01
      • 1970-01-01
      • 2016-11-14
      • 2011-08-22
      相关资源
      最近更新 更多