Reputation: 6655
Quoting from one of the unix programming books,
When a C program is executed by the kernelby, one of the exec functions calls special
start-up routine
. This function is called before the main function is called. The executable program file specifies this routine as the starting address for the program; this is set up by the link editor when it is invoked by the C compiler. This start-up routine takes values from the kernel the command-line arguments and the environment and sets things up so that the main function is called as shown earlier.
Why do we a need a middle man start-up routine
. The exec function could have straightway called the main function and the kernel could have directly passed the command line arguments and environment to the main function. Why do we need the start-up routine in between?
Upvotes: 4
Views: 4030
Reputation: 1
Important to know also is that an application program is executed in user mode, and any system calls out, set the privileged bit and go into kernel mode. This helps increase OS security by preventing the user from accessing kernel level system calls and a myriad of other complications. So a call to printf will trap, set kernel mode bit, execute code, then reset to user mode and return to your application.
The CRT is required to help you and allow you to use the languages you want in Windows and Linux. it provides some very fundamental bootstrapping into the OS to provide you with feature sets for development.
Upvotes: 0
Reputation: 47034
Calling main()
is a C thing, while calling _start()
is a kernel thing, indicated by the entry point in the binary format header. (for clarity: the kernel doesn't want or need to know that we call it _start
)
If you would have a non-C binary, you might not have a main()
function, you might not even have the concept of a "function" at all.
So the actual question would be: why doesn't a compiler give the address of main()
as a starting point? That's because typical libc implementations want to do some initializations before really starting the program, see the other answers for that.
edit as an example, you can change the entry point like this:
$ cat entrypoint.c
int blabla() { printf("Yes it works!\n"); exit(0); }
int main() { printf("not called\n"); }
$ gcc entrypoint.c -e blabla
$ ./a.out
Yes it works!
Upvotes: 5
Reputation: 328556
Because C has no concept of "plug in". So if you want to use, say, malloc()
someone has to initialize the necessary data structures. The C programmers were lazy and didn't want to have to write code like this all the time:
main() {
initialize_malloc();
initialize_stdio();
initialize_...();
initialize_...();
initialize_...();
initialize_...();
initialize_...();
... oh wow, can we start already? ...
}
So the C compiler figures out what needs to be done, generates the necessary code and sets up everything so you can start with your code right away.
Upvotes: 10
Reputation: 9404
The start-up routine initializes the CRT (i.e. creates the CRT heap so that malloc
/free
work, initializes standard I/O streams, etc.); in case of C++ it also calls the globals' constructors. There may be other system-specific setup, you should check the sources of your run-time library for more details.
Upvotes: 5