You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86-32与x64汇编中固定大小缓冲区栈分配差异(GCC未优化C)

x64与x86-32汇编栈空间分配差异的原因

问题背景

同样的未优化C代码(定义500字节char buffer[500]),用GCC编译的x64汇编会为缓冲区分配额外空间,而x86-32汇编仅分配准确的500字节,仅架构不同,差异原因如下:

我的C代码

#include <stdio.h>
#include <string.h>

int main (int argc, char** argv){
    char buffer[500];
    strcpy(buffer, argv[1]);
    return 0;
}

编译后的x64汇编片段

0x0000000000001139 <+0>:     push   %rbp
   0x000000000000113a <+1>:     mov    %rsp,%rbp
   0x000000000000113d <+4>:     sub    $0x210,%rsp  // 分配528字节栈空间
   0x0000000000001144 <+11>:    mov    %edi,-0x204(%rbp)  // 保存argc(4字节)
   0x000000000000114a <+17>:    mov    %rsi,-0x210(%rbp)  // 保存argv(8字节)
   0x0000000000001151 <+24>:    mov    -0x210(%rbp),%rax
   0x0000000000001158 <+31>:    add    $0x8,%rax
   0x000000000000115c <+35>:    mov    (%rax),%rdx
   0x000000000000115f <+38>:    lea    -0x200(%rbp),%rax  // buffer起始地址:rbp-512
   0x0000000000001166 <+45>:    mov    %rdx,%rsi
   0x0000000000001169 <+48>:    mov    %rax,%rdi
   0x000000000000116c <+51>:    call   0x1030 <strcpy@plt>
   0x0000000000001171 <+56>:    mov    $0x0,%eax
   0x0000000000001176 <+61>:    leave  
   0x0000000000001177 <+62>:    ret  

差异原因分析

  • 栈对齐规则不同:
    x64平台遵循System V AMD64 ABI,要求调用任何函数前栈指针(rsp)必须是16字节的整数倍。进入main函数时,push %rbp会让rsp减少8字节(从调用前的16对齐变为8对齐),因此需要额外分配空间调整rsp回到16对齐状态。500字节不是16的倍数(500 ÷ 16 = 31余4),必须补充空间满足对齐要求。而x86-32通常仅要求4字节对齐,500刚好是4的整数倍(500 ÷ 4 = 125),无需额外空间。

  • 寄存器宽度与参数存储差异:
    x64的通用寄存器是8字节宽度,保存argv(8字节指针)需要8字节栈空间,而argc(4字节整数)为了对齐到8字节边界,会额外占用4字节填充空间;x86-32的寄存器是4字节,argc和argv各占4字节,总共8字节,无需额外填充。这部分差异也会导致x64分配的栈空间比x86-32多。

内容的提问来源于stack exchange,提问作者JamesMcC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:10:43