c - 静态变量在栈上的空间分配

标签 c stack buffer disassembly

以下代码包含一个 8 字节缓冲区。

void vuln() {
    char buffer[8];
    gets(buffer);
    printf("%s",buffer);
}

int main() {
    vuln();
    return 0;
}

因此,预计只会为此缓冲区保留 8 个字节的堆栈。但反汇编显示有 16 个字节被保留。

(gdb) 
Dump of assembler code for function vuln:
   0x000000000040057d <+0>:     push   %rbp
   0x000000000040057e <+1>:     mov    %rsp,%rbp
   0x0000000000400581 <+4>:     sub    $0x10,%rsp
   0x0000000000400585 <+8>:     lea    -0x10(%rbp),%rax
   0x0000000000400589 <+12>:    mov    %rax,%rdi
   0x000000000040058c <+15>:    callq  0x400480 <gets@plt>
   0x0000000000400591 <+20>:    lea    -0x10(%rbp),%rax
   0x0000000000400595 <+24>:    mov    %rax,%rsi
   0x0000000000400598 <+27>:    mov    $0x400644,%edi
   0x000000000040059d <+32>:    mov    $0x0,%eax
   0x00000000004005a2 <+37>:    callq  0x400450 <printf@plt>
   0x00000000004005a7 <+42>:    leaveq 
   0x00000000004005a8 <+43>:    retq   
End of assembler dump.

某些操作将根据自动化脚本中堆栈上缓冲区的预期大小来执行。但这破坏了剧本。我可以知道为什么为缓冲区分配 16 个字节以便我可以将其合并到脚本中吗?

最佳答案

x86-64 ELF psABI要求堆栈指针对齐:第3.2.2节(“堆栈框架”)说

... The end of the input argument area shall be aligned on a 16 byte boundary. In other words, the value (%rsp− 8) is always a multiple of 16 when control is transferred to the function entry point. The stack pointer, %rsp, always points to the end of the latest allocated stack frame.

您的函数在堆栈上分配 8 个字节,然后调用单参数函数 gets;该函数的一个参数在寄存器中传递,因此为了维持 ABI 要求,编译器必须在调用函数之前将堆栈指针向下移动 8 个字节。

关于c - 静态变量在栈上的空间分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24675817/

相关文章:

c - 使用 FFTW 取消定义架构 x86_64 的符号

objective-c - 在 Objective C 中创建堆栈

Java NIO ByteBuffer,翻转后写入

c - 将 jpeg 文件读取到 char* 缓冲区 c

java - 如何根据第一个字节解析不同的数据包类型

c++ - GNU gcc mysys make 命令没有规则来生成目标 libpng

c - 预处理器条件分布在 `#include` 个文件中

c - 按位取余运算符

C struct object Stack - 常量表达式中不允许函数调用(错误)

c++ - 哪个更快 : STL queue or STL stack?