汇编:局部变量的堆栈空间过多

时间:2011-12-26 22:31:13

标签: assembly

我目前正在尝试很好地理解一些汇编代码,以便从中重构C代码。虽然我已经接近完成了,但有一点关于局部变量让我感到困惑。

使用Base Pointer esp访问局部变量并减去它们的偏移量,例如: -0xc(%ebp)引用局部变量。要将其解释为C代码,我需要知道这些变量的大小(至少如果它们是数组)。可以通过计算与其他变量的偏移的差异来做到这一点。如果存在局部变量-0xc(%ebp)-0x8(%ebp),我们知道-0xc(%ebp)最有可能是4个字节长。但是,如果在反汇编中没有其他任何本地变量的访问权限,那么-0x8(%ebp)呢?我们可以建议它的大小必须是8个字节吗?我不这么认为......

我的问题是:编译器似乎为局部变量留出了比需要更多的空间。让我告诉你这个简单的例子:一个错误函数,用gdb反汇编。

push   %ebp              
mov    %esp,%ebp      
sub    $0x8,%esp               // 0x8 = 8 byte for local variables
mov    0x8(%ebp),%eax          // errormsg is a function argument  
mov    %eax,(%esp)             
call   0x80485cc <perror@plt>  // perror(errormsg)
movl   $0x1,(%esp)                 
call   0x804866c <exit@plt>    // exit(1)

这个函数显然不会访问任何局部变量,所以我们可以怀疑没有。但仍有8个字节留给局部变量,不存在吗?

这不是我见过的唯一一个为不需要的变量分配空间的例子。我想我忽略了一些东西,但是只要我这样做,我就无法找到编写C代码所需的所有变量的大小。

有什么建议吗?

提前致谢!

1 个答案:

答案 0 :(得分:3)

此处的mov %eax,(%esp)指令用于代替push。因此,虽然没有使用任何局部变量,但它不像浪费的保留堆栈空间。当然,当它只需要保留4时,看起来该函数为局部变量保留8个字节,但也许这是编译器使用的约定:始终以8个字节的块保留堆栈。保持堆栈qword对齐有一定的意义。