c - 为什么 gcc 反汇编程序为局部变量分配额外的空间?

标签 c optimization assembly compiler-construction gdb

我已经用 C 编写了简单的函数,

void GetInput()
{
    char buffer[8];
    gets(buffer);
    puts(buffer);
}

当我在 gdb 的反汇编器中反汇编它时,它给出了以下反汇编。

   0x08048464 <+0>: push   %ebp
   0x08048465 <+1>: mov    %esp,%ebp
   0x08048467 <+3>: sub    $0x10,%esp
   0x0804846a <+6>: mov    %gs:0x14,%eax
   0x08048470 <+12>:    mov    %eax,-0x4(%ebp)
   0x08048473 <+15>:    xor    %eax,%eax
=> 0x08048475 <+17>:    lea    -0xc(%ebp),%eax
   0x08048478 <+20>:    mov    %eax,(%esp)
   0x0804847b <+23>:    call   0x8048360 <gets@plt>
   0x08048480 <+28>:    lea    -0xc(%ebp),%eax
   0x08048483 <+31>:    mov    %eax,(%esp)
   0x08048486 <+34>:    call   0x8048380 <puts@plt>
   0x0804848b <+39>:    mov    -0x4(%ebp),%eax
   0x0804848e <+42>:    xor    %gs:0x14,%eax
   0x08048495 <+49>:    je     0x804849c <GetInput+56>
   0x08048497 <+51>:    call   0x8048370 <__stack_chk_fail@plt>
   0x0804849c <+56>:    leave  
   0x0804849d <+57>:    ret    

现在请看第三行,0x08048467 <+3>: sub $0x10,%esp ,我只有 8 个字节分配为局部变量,那么为什么编译器分配 16 个字节(0x10)。

其次,xor %gs:0x14,%eax是什么意思? .

@Edit:如果是优化,有什么办法可以阻止。

谢谢。

最佳答案

两件事:

  1. 编译器可能会为您没有在源代码中命名的中间表达式保留空间(或者相反,不会为可以完全存在于寄存器中的局部变量分配空间)。二进制文件中的堆栈槽列表不必与源代码中的局部变量列表相匹配。
  2. 在某些平台上,编译器必须保持堆栈指针对齐。对于您问题中的特定示例,编译器可能正在努力使堆栈指针与 16 字节的边界对齐。

关于您应该单独提出的其他问题,xor %gs:0x14,%eax 显然是 stack protection mechanism 的一部分,默认启用。如果您使用的是 GCC,请使用 -fno-stack-protector 将其关闭。

关于c - 为什么 gcc 反汇编程序为局部变量分配额外的空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20865235/

相关文章:

c++ - 如何优化简单的高斯滤波器的性能?

algorithm - 不限制访问次数的旅行商问题

程序集在打印消息时跳过第一个符号

c - OpenGL 广告牌插值问题

c - 迷宫生成器

使用 malloc 连接字符串

android - 如何将 C++ 源代码解析为 obj?

c - 什么时候发生不可读内存页?

php - 使用复合聚合函数的数组子集优化

assembly - 将 ARM 汇编助记符转换为字节