初识main函数

发布于:2025-05-24 ⋅ 阅读:(13) ⋅ 点赞:(0)
int main(int argc, char *argv[])
{
    int a = 0;
    return a;
}

X64

MSVC编译器

Windows x64调用约定

{
// 将第二个参数(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调用约定

        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) 偏移寻址)。

网站公告

今日签到

点亮在社区的每一天
去签到