怀疑堆栈指针

时间:2016-01-07 09:26:36

标签: c assembly x86

考虑一个程序:

#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&gt; test.dis

我为函数&#34; function&#34;

获得以下转储
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个字节?

我在英特尔处理器上运行64位ubuntu 14.04

1 个答案:

答案 0 :(得分:7)

来自the GCC documentation

  

-mpreferred-stack-boundary = NUM
  尝试保持堆栈边界与2上升到 num 字节边界对齐。如果未指定-mpreferred-stack-boundary默认值为 4( 16字节或128位),除非优化代码大小(-Os),在这种情况下,默认值是最小的正确对齐(x86为4个字节,x86-64为8个字节)。

因此,当堆栈为数组分配空间时,堆栈也在16字节的默认边界上对齐。在第一种情况下,您有15个字节的数据小于16,因此分配了16个字节。在第二种情况下,你有17个字节的数据超过16但小于(16的下一个数字)32,所以分配了32个字节的空间。