C语言 _start() 在 C 中有什么用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29694564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the use of _start() in C?
提问by SimpleGuy
I learned from my colleague that one can write and execute a C program without writing a main()function. It can be done like this:
我从我的同事那里了解到,无需编写main()函数即可编写和执行 C 程序。可以这样做:
my_main.c
my_main.c
/* Compile this with gcc -nostartfiles */
#include <stdlib.h>
void _start() {
int ret = my_main();
exit(ret);
}
int my_main() {
puts("This is a program without a main() function!");
return 0;
}
Compile it with this command:
用这个命令编译它:
gcc -o my_main my_main.c –nostartfiles
Run it with this command:
使用以下命令运行它:
./my_main
When would one need to do this kind of thing? Is there any real world scenario where this would be useful?
什么时候需要做这种事情?是否有任何真实世界的场景这会有用?
采纳答案by fuz
The symbol _startis the entry pointof your program. That is, the address of that symbol is the address jumped to on program start. Normally, the function with the name _startis supplied by a file called crt0.owhich contains the startup code for the C runtime environment. It sets up some stuff, populates the argument array argv, counts how many arguments are there, and then calls main. After mainreturns, exitis called.
符号_start是程序的入口点。也就是说,那个符号的地址就是程序开始时跳转到的地址。通常,具有该名称的函数_start由一个被调用的文件提供,该文件crt0.o包含 C 运行时环境的启动代码。它设置一些东西,填充参数数组argv,计算有多少参数,然后调用main. 后main返回时,exit被调用。
If a program does not want to use the C runtime environment, it needs to supply its own code for _start. For instance, the reference implementation of the Go programming language does so because they need a non-standard threading model which requires some magic with the stack. It's also useful to supply your own _startwhen you want to write really tiny programs or programs that do unconventional things.
如果程序不想使用 C 运行时环境,则需要为_start. 例如,Go 编程语言的参考实现这样做是因为它们需要一个非标准的线程模型,这需要对堆栈进行一些魔术。_start当您想编写非常小的程序或执行非常规事情的程序时,提供您自己的程序也很有用。
回答by MikeMB
While mainis the entry point for your program from a programmers perspective, _startis the usual entry point from the OS perspective (the first instruction that is executed after your program was started from the OS)
虽然main从程序员的角度来看_start是程序的入口点,从操作系统的角度来看是通常的入口点(从操作系统启动程序后执行的第一条指令)
In a typical C and especially C++ program, a lot of work has been done before the execution enters main. Especially stuff like initialization of global variables.Hereyou can find a good explanation of everything that's going on between _start()and main()and also after main has exited again (see comment below).
The necessary code for that is usually provided by the compiler writers in a startup file, but with the flag –nostartfilesyou essentially tell the compiler: "Don't bother giving me the standard startup file, give me full control over what is happening right from the start".
在一个典型的 C 尤其是 C++ 程序中,在执行进入 main 之前已经做了很多工作。特别是像全局变量的初始化之类的东西。在这里,您可以找到对main 再次退出之间_start()和main()之后发生的所有事情的很好的解释(请参阅下面的评论)。
必要的代码通常由编译器编写者在启动文件中提供,但是–nostartfiles你本质上是告诉编译器的标志:“不要费心给我标准的启动文件,让我完全控制从开始”。
This is sometimes necessary and often used on embedded systems. E.g. if you don't have an OS and you have to manually enable certain parts of your memory system (e.g. caches) before the initialization of your global objects.
这有时是必要的,并且经常用于嵌入式系统。例如,如果您没有操作系统,并且您必须在初始化全局对象之前手动启用内存系统的某些部分(例如缓存)。
回答by Trevor
When would one need to do this kind of thing?
什么时候需要做这种事情?
When you want your own startup code for your program.
当您想要自己的程序启动代码时。
mainis not the first entry for a C program, _startis the first entry behind the curtain.
main不是 C 程序_start的第一个条目,而是幕后的第一个条目。
Example in Linux:
Linux 中的示例:
_start: # _start is the entry point known to the linker
xor %ebp, %ebp # effectively RBP := 0, mark the end of stack frames
mov (%rsp), %edi # get argc from the stack (implicitly zero-extended to 64-bit)
lea 8(%rsp), %rsi # take the address of argv from the stack
lea 16(%rsp,%rdi,8), %rdx # take the address of envp from the stack
xor %eax, %eax # per ABI and compatibility with icc
call main # %edi, %rsi, %rdx are the three args (of which first two are C standard) to main
mov %eax, %edi # transfer the return of main to the first argument of _exit
xor %eax, %eax # per ABI and compatibility with icc
call _exit # terminate the program
Is there any real world scenario where this would be useful?
是否有任何真实世界的场景这会有用?
If you mean, implement our own _start:
如果你的意思是,实现我们自己的_start:
Yes, in most of the commercial embedded software I have worked with, we need to implement our own _startregarding to our specific memory and performance requirements.
是的,在我使用过的大多数商业嵌入式软件中,我们需要_start根据我们的特定内存和性能要求实现我们自己的。
If you mean, drop the mainfunction and change it to something else:
如果您的意思是,请删除该main功能并将其更改为其他内容:
No, I don't see any benefit doing that.
不,我认为这样做没有任何好处。
回答by ulidtko
Hereis a good overview of what happens during program startup beforemain. In particular, it shows that __startis the actual entry pointto your program from OS viewpoint.
这里很好地概述了之前程序启动期间发生的情况main。特别是,它表明从操作系统的角度来看,它__start是您程序的实际入口点。
It is the very first address from which the instruction pointerwill start counting in your program.
它是程序中指令指针开始计数的第一个地址。
The code there invokes some C runtime library routines just to do some housekeeping, then call your main, and then bring things down and call exitwith whatever exit code mainreturned.
那里的代码调用一些 C 运行时库例程只是为了做一些内务处理,然后调用您的main,然后将事情放下并exit使用main返回的任何退出代码调用。
A picture is worth a thousand words:
一张图片胜过千言万语:


P.S: this answer is transplanted from another questionwhich SO has helpfully closed as duplicate of this one.

