What is the need for a C startup procedure?

Quote from one of the unix programming books,

When C runs kernelby, one of the exec functions calls a special start-up routine . This function is called before the main function is called. The executable file program file indicates this procedure as the starting address of the program; this is configured by the link editor when it is called by the C compiler. This startup procedure accepts values ​​from the kernel command line arguments and the environment and that the main function is called shown earlier.

Why do we need an average person start-up routine . The exec function could immediately call the main function, and the kernel could directly pass command line arguments and the environment of the main function. Why do we need a startup procedure between them?

+4
source share
4 answers

Because C has no concept of "connect." Therefore, if you want to use, say, malloc() , someone must initialize the necessary data structures. C programmers were lazy and did not want them to constantly write code:

 main() { initialize_malloc(); initialize_stdio(); initialize_...(); initialize_...(); initialize_...(); initialize_...(); initialize_...(); ... oh wow, can we start already? ... } 

So, the C compiler calculates what needs to be done, generates the necessary code and configures everything so that you can immediately start your code.

+9
source

The startup procedure initializes the CRT (i.e., creates a bunch of CRTs so that malloc / free works, initializes standard input / output streams, etc.); in case of C ++, it also calls the globals constructors. There may be other system settings, you should check the sources of your runtime library for more details.

+5
source

The call to main() is a substance of C, and the call to _start() is the kernel item indicated by the entry point in the binary header. (for clarity: the kernel does not want or should not know what we call it _start )

If you have non-C binary, you may not have a main() function, you cannot even have the concept of a function at all.

So the real question is: why does the compiler not give the address of main() as a starting point? This is because typical libc implementations want to do some initialization before starting the program, see Other answers for this.

edit , you can change the entry point as follows:

 $ 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! 
+4
source

It is also important to know that the application program runs in user mode, and any system is invoked, sets the privileged bit, and enters kernel mode. This helps improve OS security by preventing the user from accessing system calls at the kernel level and many other complications. Thus, calling printf will catch a trap, set the kernel mode bit, execute the code, then reset to user mode and return to your application.

CRT is needed to help you and allow you to use the languages ​​you want to use on Windows and Linux. it provides some very fundamental OS loading to provide you with a set of development features.

0
source

Source: https://habr.com/ru/post/1334236/