Almost all programmers in the first class are learning HelloWorld program, let's go over the classic C language Helloworl
Copy Code code as follows:
* HELLO.C * *
#include <stdio.h>
int main ()
{
printf ("Hello world!\n");
return 0;
}
This is a simple can not be a single program, but it contains the most important part of the program, which is the main function we see in almost all of the code, we compile the executable file and look at the symbol table, filter out the functions in the following (for easy viewing I've manually adjusted the format of grep's output, So it's not the same as your output format.
Copy Code code as follows:
$ gcc Hello.c-o Hello
$ readelf-s Hello | grep FUNC
Num:value Size Type Bind Vis Ndx Name
27:000000000040040c 0 FUNC Local DEFAULT call_gmon_start
32:0000000000400430 0 FUNC Local DEFAULT __do_global_dtors_aux
35:00000000004004a0 0 FUNC Local DEFAULT frame_dummy
40:0000000000400580 0 FUNC Local DEFAULT __do_global_ctors_aux
47:00000000004004E0 2 FUNC GLOBAL DEFAULT __libc_csu_fini
48:00000000004003e0 0 FUNC GLOBAL DEFAULT _start
51:0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@ @GLIBC_2.2.5
52:00000000004005b8 0 FUNC GLOBAL DEFAULT _fini
53:0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@ @GLIBC_
58:00000000004004F0 137 FUNC GLOBAL DEFAULT __libc_csu_init
62:00000000004004C4 FUNC GLOBAL DEFAULT Main
63:0000000000400390 0 FUNC GLOBAL DEFAULT _init
Everyone knows that the user's code starts with the main function, although we only write a main function, but from the above function table we can see that there are many other functions, such as the _start function. Actually, the actual entry of the program is not the main function, we compile the HELLO.C code with the following command
Copy Code code as follows:
$ gcc Hello.c-nostdlib
/usr/bin/ld:warning:cannot find entry symbol _start; Defaulting to 0000000000400144
-nostdlib command is not linked to the standard library, the error is said to find entry symbol _start, here is said to find the entry symbol _start, that is, the real entry of the program is the _start function
In fact, the main function is just the user code entry, it will be called by the system library, before the main function, the system library will do some initialization work, such as the allocation of global variables of memory, initialization heap, thread, etc., when the main function is completed, the exit () function to do some cleanup work, Users can implement _start functions themselves
Copy Code code as follows:
* HELLO_START.C * *
#include <stdio.h>
#include <stdlib.h>
_start (void)
{
printf ("Hello world!\n");
Exit (0);
}
Execute the following compile command and run
Copy Code code as follows:
$ gcc Hello_start.c-nostartfiles-o hello_start
$./hello_start
Hello world!
The-nostartfiles feature here is the standard system startup files when linking, which is not using the standard startup files, but also links the systems library. So the program can still be executed. Again we look at the symbol table
Copy Code code as follows:
$ readelf-s Hello_start | grep FUNC
Num:value Size Type Bind Vis Ndx Name
20:0000000000400350 FUNC GLOBAL DEFAULT _start
21:0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@ @GLIBC_2.2.5
22:0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@ @GLIBC_2.2.5
Now there are only three functions left, and are all implemented by ourselves, in which printf because only one parameter will be optimized by the compiler to the puts function, the compile-time plus-fno-builtin option to turn off the optimization
If we remove the exit (0) statement in the _start function, the execution of the program will be core, because the _start function completes the program, and the _start we implement does not call exit () to clean up the memory
Finally removed the main function, then found that there must be a _start function, is not annoying, in fact, the _start function is just a default entry, we can specify the entrance of the
Copy Code code as follows:
* HELLO_NOMAIN.C * *
#include <stdio.h>
#include <stdlib.h>
int Nomain ()
{
printf ("Hello world!\n");
Exit (0);
}
compile with the following command
Copy Code code as follows:
$ gcc hello_nomain.c-nostartfiles-e nomain-o hello_nomain
Where the-e option can specify a program entry symbol, view the symbol table as follows
Copy Code code as follows:
$ readelf-s Hello_nomain | grep FUNC
Num:value Size Type Bind Vis Ndx Name
20:0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@ @GLIBC_2.2.5
21:0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@ @GLIBC_2.2.5
22:0000000000400350 FUNC GLOBAL DEFAULT nomain
Compared to the Hello_start symbol table found that only _start replaced the Nomain
It's clear to us here, the default entry of the program is the _start function in the standard library, it will do some initialization work, call the user's main function, and finally do some cleanup work, we can write our own _start function to cover the _start in the standard library, even can specify the entrance of the program