考虑一个程序:
#include <stdio.h>
void function(int a, int b, int c){
char buffer1[5];
char buffer2[10];
}
void main(){
function(1,2,3);
}
用
编译这个
gcc test.c -m32 -g -o test -fno-stack-protector
和做
objdump -S 测试 > test.dis
我得到函数“function”的以下转储
void function(int a, int b, int c){
80483ed: 55 push %ebp
80483ee: 89 e5 mov %esp,%ebp
80483f0: 83 ec 10 sub $0x10,%esp
char buffer1[5];
char buffer2[10];
}
考虑同一程序的另一个变体:
#include <stdio.h>
void function(int a, int b, int c){
char buffer1[7];
char buffer2[10];
}
void main(){
function(1,2,3);
}
关于使用相同的命令编译和生成转储,我得到:
void function(int a, int b, int c){
80483ed: 55 push %ebp
80483ee: 89 e5 mov %esp,%ebp
80483f0: 83 ec 20 sub $0x20,%esp
char buffer1[7];
char buffer2[10];
}
我的问题是,是什么导致堆栈指针在第一种情况下减少 16,在第二种情况下减少 32,而在第二种情况下只需要再增加 2 个字节?
我在 Intel 处理器上运行 64 位 ubuntu 14.04
最佳答案
-mpreferred-stack-boundary
=num
Attempt to keep the stack boundary aligned to a 2 raised to num byte boundary. If-mpreferred-stack-boundary
is not specified, the default is 4 (16 bytes or 128 bits), except when optimizing for code size (-Os
), in which case the default is the minimum correct alignment (4 bytes for x86, and 8 bytes for x86-64).
因此,由于在堆栈上为数组分配了空间,因此堆栈也在 16 字节的默认边界上对齐。在第一种情况下,您有 15 个字节的数据,小于 16 个字节,因此分配了 16 个字节。在第二种情况下,您有 17 个字节的数据,它大于 16 但小于(16 的下一个倍数)32,因此分配了 32 个字节的空间。
关于c - 关于栈指针的疑问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34651487/