当加载器运行时,它创建如下图所示的存储器映像。
在可执行文件中段表头的指导下,加载器将可执行文件的相关内容拷贝到代码和数据段。
接下来,加载器跳转到程序的入口点,也就是符号 _start
的地址。在 _start
地址处的 启动代码(startup code)是在目标文件 ctrl.o
中定义的,对所有的 C 程序都是一样的。
下图是启动代码中特殊的调用序列:
对调用序列更详细的说明见文章加载可执行目标文件。
现在来回答问题:每个程序都需要一个 main
函数,因为 C 的启动代码对于每个程序而言都是相同的,要跳转到一个叫做 main
的函数上。
main
以 return
语句终止,那么控制传递回启动程序,该程序通过调用 _exit
再将控制返回给操作系统。return
语句,也会发生相同的情况。main
是以调用 exit
终止的,那么 exit
将最终通过调用 _exit
将控制返回给操作系统。在这三种情况中,最终效果是相同的:当 main
完成时,控制会返回给操作系统。