[英]What is __libc_start_main and _start?
从过去几天开始,我一直试图了解当我们执行 C 程序时幕后会发生什么。 但是,即使在阅读了许多帖子之后,我也找不到详细而准确的解释。 有人可以帮我吗?
在编译和链接程序时,您通常会为特定用途找到像这样的特殊名称。
通常,像_start
这样的东西是可执行文件的实际入口点,它将位于某些 object 文件或库中(如 C 运行时启动代码的crt0.o
) - 这通常会自动添加到您的可执行文件中通过 linker,类似于添加 C 运行时库的方式(a) 。
用于启动程序的操作系统代码将类似于(显然是伪代码,并且错误检查比应有的要少得多):
def spawnProg(progName):
id = newProcess() # make process address space
loadProgram(pid = id, file = progName) # load program into it
newThread(pid, initialPc = '_start') # make new thread to run it
即使您在 C 中编码时自己创建了一个main
,但这并不是事情真正开始发生的地方。 甚至在您的主程序启动之前,还有很多事情需要完成。 因此,C 启动代码的内容将类似于(最简单的):
_start: ;; Weave magic here to set up C and libc.
call __setup_for_c ; set up C environment
call __libc_start_main ; set up standard library
call _main ; call your main
call __libc_stop_main ; tear down standard library
call __teardown_for_c ; tear down C environment
jmp __exit ; return to OS
“魔法编织”是使环境为 C 程序做好准备所需的一切。 这可能包括以下内容:
argc
和argv
,甚至准备堆栈本身(有可能用于 C 的特定调用约定,并且很可能操作系统在调用_start
时根本不需要设置堆栈,因为需要过程未知); 只有在所有这些都完成后,才能调用您的main
function。 也有可能在您的main
退出后需要完成工作,例如:
atexit
处理程序(您希望在退出时自动运行的事情,无论退出发生在哪里); (a)如果您正在编写不使用标准 C 库的东西,或者如果您想为低级工作提供自己的_start
例程,则可以告诉许多链接器不要这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.