为什么我的堆栈指针只能以16的倍数递增?

7

使用以下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字节为增量增长。这种情况为什么会发生?它是所有平台都会出现,还是特定于某个平台?
我目前在Intel Mac上运行OSX,在通过Ubuntu(32位)VirtualBox客户端使用GCC编译。
3个回答

9

来自GCC man page,(加粗是我自己加的):

-mpreferred-stack-boundary=num

尝试将堆栈边界对齐到2的num次方个字节的边界。如果未指定-mpreferred-stack-boundary默认值为4(16字节或128位)


1
编译器这样做的原因是,访问未对齐的内存位置的某些指令会受到性能惩罚。 - vidstige
谢谢,通过这个答案和vidstige的评论,我得到了所需的信息 :) - Martin Doms
2
@vidstige @Martin:或者它们会崩溃,即使在x86上(例如,查看movaps)。 - Bahbar

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

我同意你的观点,但那不应该是一个答案。那实际上是对楼主问题的提问。 - andreee

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接