初识main函数

cpp 复制代码
int main(int argc, char *argv[])
{
    int a = 0;
    return a;
}

X64

MSVC编译器

Windows x64调用约定

cpp 复制代码
{
// 将第二个参数(rdx)保存到栈[rsp+0x10]位置
0x7ff6e54c2ad0                   mov     qword ptr [rsp+10h],rdx 
// 将第一个参数(ecx)保存到栈[rsp+8]位置
0x7ff6e54c2ad5  <+    5>         mov     dword ptr [rsp+8],ecx
//保存rdi寄存器(非易失性寄存器) 保存rdi是因为函数可能会修改它,遵循调用约定
0x7ff6e54c2ad9  <+    9>         push    rdi
0x7ff6e54c2ada  <+   10>         sub     rsp,10h
        4        int a = 0;
0x7ff6e54c2ade  <+   14>         mov     dword ptr [rsp],0
        5        return a;
0x7ff6e54c2ae5  <+   21>         mov     eax,dword ptr [rsp]
        6    
}
// 释放栈空间
0x7ff6e54c2ae8  <+   24>         add     rsp,10h
// 恢复rdi寄存器
0x7ff6e54c2aec  <+   28>         pop     rdi
0x7ff6e54c2aed  <+   29>         ret

GCC/MinGW

System V x64调用约定

cpp 复制代码
        4 [1]	{
0x4016a0                  55                    push   %rbp
0x4016a1  <+    1>        48 89 e5              mov    %rsp,%rbp
0x4016a4  <+    4>        48 83 ec 30           sub    $0x30,%rsp
0x4016a8  <+    8>        89 4d 10              mov    %ecx,0x10(%rbp)
0x4016ab  <+   11>        48 89 55 18           mov    %rdx,0x18(%rbp)
0x4016af  <+   15>        e8 bc 04 00 00        call   0x401b70 <__main>
        5 [1]	    int a = 0;
//局部变量 a 存储在 -0x4(%rbp)(栈帧内固定偏移)
0x4016b4  <+   20>        c7 45 fc 00 00 00 00  movl   $0x0,-0x4(%rbp)
        6 [1]	    return a;
0x4016bb  <+   27>        8b 45 fc              mov    -0x4(%rbp),%eax
        7 [1]	}
0x4016be  <+   30>        48 83 c4 30           add    $0x30,%rsp
0x4016c2  <+   34>        5d                    pop    %rbp
0x4016c3  <+   35>        c3                    ret

对比

特性 第一段代码(Windows x64) 第二段代码(System V x64)
调用约定 Windows x64 System V x64(Linux/macOS)
参数传递 ecx, rdx, r8, r9 rdi, rsi, rdx, rcx, r8, r9
栈帧管理 直接调整 rsp ,无 rbp 传统 push rbp / mov rbp, rsp
Shadow Space 通常 32 字节(此处仅 16 字节)
局部变量存储 [rsp] (栈顶) -0x4(%rbp) (栈帧偏移)
非易失寄存器保存 显式保存 rdi 调用者负责保存
函数返回 ret(或 ret 0 ret
典型使用场景 Windows 程序 Linux/macOS 程序
  1. 调用约定差异
    • Windows x64 和 System V x64 在参数传递、栈管理上完全不同。
    • Windows 需要 shadow space,System V 需要栈对齐。
  2. 栈帧管理
    • Windows x64 常省略 rbp,直接操作 rsp
    • System V x64 保留传统栈帧(rbp)。
  3. 寄存器保存
    • Windows x64 可能显式保存非易失寄存器(如 rdi)。
    • System V x64 由调用者保存非易失寄存器。
  4. 代码风格
    • Windows x64 更紧凑(如 [rsp+8] 直接寻址)。
    • System V x64 更传统(如 -0x4(%rbp) 偏移寻址)。
相关推荐
仰泳的熊猫23 分钟前
LeetCode:785. 判断二分图
数据结构·c++·算法·leetcode
^Moon^26 分钟前
CycloneDDS:跨主机多进程通信全解析
c++·分布式·dds
C_Liu_2 小时前
C++:list
开发语言·c++
my rainy days3 小时前
C++:友元
开发语言·c++·算法
鄃鳕4 小时前
python 字典 列表 类比c++【python】
c++·python
保持低旋律节奏4 小时前
C++——list链表
c++·链表·list
2401_841495646 小时前
【数据结构】基于Floyd算法的最短路径求解
java·数据结构·c++·python·算法··floyd
纵有疾風起7 小时前
C++模版:模板初阶及STL简介
开发语言·c++·经验分享·开源
QT 小鲜肉7 小时前
【个人成长笔记】Qt Creator快捷键终极指南:从入门到精通
开发语言·c++·笔记·qt·学习·学习方法
CHANG_THE_WORLD7 小时前
switch语句在汇编层面的几种优化方式 ,为什么能进行优化
汇编·算法·switch·汇编分析·switch case·switch case 汇编·switch case 语句