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

MacOS下编译程序为何无_start函数?探究程序入口与栈初始化

macOS程序入口与栈初始化疑惑:为何反汇编未显示_start函数?

示例代码

int main (int argc, char **argv) {}

执行命令与输出

% gcc main.c && otool -xv a.out
a.out:
(__TEXT,__text) section
_main:
0000000100003f9e    pushq   %rbp
0000000100003f9f    movq    %rsp, %rbp
0000000100003fa2    movl    %edi, -0x4(%rbp)
0000000100003fa5    movq    %rsi, -0x10(%rbp)
0000000100003fa9    movl    $0x0, %eax
0000000100003fae    popq    %rbp
0000000100003faf    retq

问题

我疑惑为何未出现_start函数,尝试反汇编是为了深入了解MacOS如何初始化栈以及程序入口的实际工作机制。查阅System V ABI文档后,栈相关章节并未给出足够启发。

解答

  1. _start不在用户可执行文件的代码段中
    gcc编译时会自动链接系统提供的启动代码(属于libSystem.dylib或crt启动对象),_start函数就包含在这些系统库文件里,而非你编写的main函数所在的可执行文件的__TEXT,__text段中。otool -xv默认只反汇编当前可执行文件的代码段,自然看不到_start。

  2. 如何查看_start的相关逻辑

  • 用nm a.out查看符号表,能看到_start是一个未定义符号(U),表示它来自外部库;
  • 使用lldb a.out调试,在启动时设置断点b _start,就能跟踪到启动代码的执行流程;
  • 若要反汇编包含_start的代码,需要指定链接的系统库,比如otool -xv /usr/lib/libSystem.dylib | grep -A 20 _start(注意不同macOS版本路径可能有变化)。
  1. macOS的栈初始化与程序入口流程
    系统内核加载可执行文件后,会先调用_start函数——它负责完成栈初始化、设置argc/argv/envp等参数、初始化C运行时环境(比如全局变量初始化、stdio缓冲区设置),最后调用你的main函数。main执行完毕后,_start还会处理返回值,调用exit函数终止进程。

  2. System V ABI不适用的原因
    macOS采用Mach-O二进制格式,遵循苹果自己的x86-64 ABI规范,和Linux使用的System V ABI存在差异,所以查阅System V文档找不到对应细节,建议参考苹果官方的x86-64调用指南或Mach-O相关文档。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:17:19