有两个简单的 C 源文件。第一个是 mainswap.c:
void swap(int *x, int *y);
int main()
{
int a, b;
a = 5;
b = 44;
swap(&a, &b);
return 0;
}
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
另一个是mainfoobar.c:
int bar(int x, int y)
{
int z = x + y;
return z;
}
int foo(int a, int b)
{
return bar(a, b);
}
int main(void)
{
foo(2, 3);
return 0;
}
我得到了两者的可重定位目标文件。而且我发现 gcc 对 in 函数的堆栈帧的对齐做了一些事情main
,mainswap.c
同时 gcc 并没有明确地为函数main
in做一些事情mainfoobar.c
。
mainswap.c的主要内容:
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $5, 24(%esp)
movl $44, 28(%esp)
leal 28(%esp), %eax
movl %eax, 4(%esp)
leal 24(%esp), %eax
movl %eax, (%esp)
call swap
movl $0, %eax
leave
ret
mainfoobar.c 的主要部分:
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $3, 4(%esp)
movl $2, (%esp)
call foo
movl $0, %eax
leave
ret
我知道andl $-16, %esp
and的意图subl $32, %esp
。相同的 gcc 版本,相同的选项,相同的计算机,唯一的区别是 C 源文件。我的问题是为什么 gcc 对两个主要函数的处理方式不同,这种现象的背后是什么?</p>
另外,我使用的gcc版本是:
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright © 2011 Free Software Foundation, Inc.
对了,在mainswap.c的函数main
中,我觉得subl $16, %esp
也能满足对齐和使用的需求,为什么gcc会浪费16个字节?</p>