def spawnProg(progName):
id = newProcess() # make process space
loadProgram(pid = id, file = progName) # load program into it
newThread(pid, initialPc = '_start') # make thread to run it
_start: ;; Weave magic here to set up C and libc.
;; Note this is example code for a mythical implementation,
;; intended to show how it could work. It is not specific
;; bound to any given implementation.
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.
1条答案
按热度按时间bnlyeluc1#
在编译和链接程序时,您通常会发现像这样的特殊名称用于特定用途。
请记住,这个答案是一般性的,而不是启动C环境的特定实现,您通常会有类似
_start
标签的东西,这将是可执行文件的 * 实际 * 入口点(从托管环境的Angular 来看)。这可能位于某个目标文件或库中(如
crt0.o
用于C运行时启动代码),通常会由链接器自动添加到可执行文件中,类似于添加C运行时库的方式(a)。用于启动程序的操作系统代码将类似于(显然是伪代码,错误检查比它应该具有的要少得多):
即使你自己在用C编写代码时创建了一个
main
,但这并不是事情真正开始发生的地方。甚至在你的主程序开始之前,还有一大堆事情需要做。因此,C启动代码的内容应该是这样的(最简单的):"魔法的编织"是指为C程序准备好环境所需要的一切。这可能包括以下内容:
argc
和argv
,甚至准备栈本身(存在可用于C的特定调用约定,并且很可能操作系统在调用_start
时 * 根本 * 不必设置栈,因为进程的需要是未知的);只有当所有这些都完成后,才可以调用
main
函数。还有一些工作需要在main
退出后完成,例如:atexit
处理程序(您希望在退出时自动运行的东西,无论退出发生在哪里);(a)例如,如果您正在编写不使用标准C库的程序,或者如果您想为底层工作提供自己的
_start
例程,那么许多链接器可能会被告知"不"这样做。