当加载器运行时,它创建如下图所示的存储器映像。

在可执行文件中段表头的指导下,加载器将可执行文件的相关内容拷贝到代码和数据段。
接下来,加载器跳转到程序的入口点,也就是符号 _start 的地址。在 _start 地址处的 启动代码(startup code)是在目标文件 ctrl.o 中定义的,对所有的 C 程序都是一样的。
下图是启动代码中特殊的调用序列:

对调用序列更详细的说明见文章加载可执行目标文件。
现在来回答问题:每个程序都需要一个 main 函数,因为 C 的启动代码对于每个程序而言都是相同的,要跳转到一个叫做 main 的函数上。
main 以 return 语句终止,那么控制传递回启动程序,该程序通过调用 _exit 再将控制返回给操作系统。return 语句,也会发生相同的情况。main 是以调用 exit 终止的,那么 exit 将最终通过调用 _exit 将控制返回给操作系统。在这三种情况中,最终效果是相同的:当 main 完成时,控制会返回给操作系统。