There is a file written in the c language. The file name is hello.c. Then I will compile as follows.
# gcc –o hello hello.c
Compiling is done in the following order.
Compile Process
Compile Process
1. Source Code( .c ) - The source code written in c language by the user has the extension c.
#include <stdio.h>
#include <stdio.h>
int main() {
printf("Hello World!\n");
}
Preprocessing
Preprocessing
2. After preprocessing, the source-preprocessing file is created with the extension i. We start to translate C language into machine language.
Compile
3. Assembly Source - A file with s extension converted to assembly language that is most similar to machine language is created.
Assembly compile
4. Object file - A binary file is created. The extension is o.
Link
5. Executable - Creates a file that can be executed by a link.
Recompile the code with these changes
(1) Add the compiler option -static.
gcc -g -O0 -fno-builtin -static -o hello hello.c
- If the static library and the shared library are together, the static library is linked first. (Consider the faster file size, but faster!)
000000000040048c <main>:
40048c: a9bf7bfd stp x29, x30, [sp, #-16]!
400490: 910003fd mov x29, sp
400494: 90000320 adrp x0, 464000 <free_mem+0x88>
400498: 911f0000 add x0, x0, #0x7c0
40049c: 94002d63 bl 40ba28 <_IO_printf>
4004a0: 52800000 mov w0, #0x0 // #0
4004a4: a8c17bfd ldp x29, x30, [sp], #16
4004a8: d65f03c0 ret
4004ac: 00000000 .inst 0x00000000 ; undefined
(2) Remove the compiler option -fno-builtin.
gcc -g -O0 -o hello hello.c
- Even if the -fno-builtin option is specified, it has the same meaning as a C library function. Many of these features are only optimized in certain cases. If it is not optimized in special cases, library function calls are emitted.
0000000000400594 <main>:
400594: a9bf7bfd stp x29, x30, [sp, #-16]!
400598: 910003fd mov x29, sp
40059c: 90000000 adrp x0, 400000 <_init-0x418>
4005a0: 9119c000 add x0, x0, #0x670
4005a4: 97ffffb7 bl 400480 <puts@plt>
4005a8: 52800000 mov w0, #0x0 // #0
4005ac: a8c17bfd ldp x29, x30, [sp], #16
4005b0: d65f03c0 ret
4005b4: 00000000 .inst 0x00000000 ; undefined
(3) Remove the compiler option -g.
gcc -O0 -o hello hello.c
-g asks the compiler and linker to generate symbol information and keep it in the executable itself.
0000000000400594 <main>:
400594: a9bf7bfd stp x29, x30, [sp, #-16]!
400598: 910003fd mov x29, sp
40059c: 90000000 adrp x0, 400000 <_init-0x418>
4005a0: 9119c000 add x0, x0, #0x670
4005a4: 97ffffb7 bl 400480 <puts@plt>
4005a8: 52800000 mov w0, #0x0 // #0
4005ac: a8c17bfd ldp x29, x30, [sp], #16
4005b0: d65f03c0 ret
4005b4: 00000000 .inst 0x00000000 ; undefined
(4) Add additional arguments to the printf() function in your program.
gcc -g -O0 -fno-builtin -o hello hello_arg.c
- The compiler will warn you about invalid placed arguments based on the format string used
0000000000400594 <main>:
#include <stdio.h>
void main()
{
400594: a9bf7bfd stp x29, x30, [sp, #-16]!
400598: 910003fd mov x29, sp
printf("Hello world",1, 2, 3, 4, 5);
40059c: 90000000 adrp x0, 400000 <_init-0x418>
4005a0: 911a0000 add x0, x0, #0x680
4005a4: 528000a5 mov w5, #0x5 // #5
4005a8: 52800084 mov w4, #0x4 // #4
4005ac: 52800063 mov w3, #0x3 // #3
4005b0: 52800042 mov w2, #0x2 // #2
4005b4: 52800021 mov w1, #0x1 // #1
4005b8: 97ffffb2 bl 400480 <printf@plt>
4005bc: d503201f nop
4005c0: a8c17bfd ldp x29, x30, [sp], #16
4005c4: d65f03c0 ret
#include <stdio.h>
void main()
{
400594: a9bf7bfd stp x29, x30, [sp, #-16]!
400598: 910003fd mov x29, sp
printf("Hello world",1, 2, 3, 4, 5);
40059c: 90000000 adrp x0, 400000 <_init-0x418>
4005a0: 911a0000 add x0, x0, #0x680
4005a4: 528000a5 mov w5, #0x5 // #5
4005a8: 52800084 mov w4, #0x4 // #4
4005ac: 52800063 mov w3, #0x3 // #3
4005b0: 52800042 mov w2, #0x2 // #2
4005b4: 52800021 mov w1, #0x1 // #1
4005b8: 97ffffb2 bl 400480 <printf@plt>
4005bc: d503201f nop
4005c0: a8c17bfd ldp x29, x30, [sp], #16
4005c4: d65f03c0 ret
(5) Move the printf() call to a separate function named output(), and call that function from main().
gcc -g -O0 -fno-builtin -o hello hello_fnc.c
00000000004005b4 <main>:
int main()
{
4005b4: a9bf7bfd stp x29, x30, [sp, #-16]!
4005b8: 910003fd mov x29, sp
hello();
4005bc: 97fffff6 bl 400594 <hello>
return 0;
4005c0: 52800000 mov w0, #0x0 // #0
}
4005c4: a8c17bfd ldp x29, x30, [sp], #16
4005c8: d65f03c0 ret
4005cc: 00000000 .inst 0x00000000 ; undefined
int main()
{
4005b4: a9bf7bfd stp x29, x30, [sp, #-16]!
4005b8: 910003fd mov x29, sp
hello();
4005bc: 97fffff6 bl 400594 <hello>
return 0;
4005c0: 52800000 mov w0, #0x0 // #0
}
4005c4: a8c17bfd ldp x29, x30, [sp], #16
4005c8: d65f03c0 ret
4005cc: 00000000 .inst 0x00000000 ; undefined
(6) Remove -O0 and add -O3 to the gcc options.
gcc -g -O3 -fno-builtin -o hello hello.c
- The -O3 option is the highest level of optimization. Treat all functions like inline functions. (The Call instruction is used, but it is recommended that you do not use it as much as possible. There is a risk of distortion because too many sources are changed.)
- The -O3 option is the highest level of optimization. Treat all functions like inline functions. (The Call instruction is used, but it is recommended that you do not use it as much as possible. There is a risk of distortion because too many sources are changed.)
0000000000400490 <main>:
#include <stdio.h>
int main() {
400490: a9bf7bfd stp x29, x30, [sp, #-16]!
printf("Hello World!\n");
400494: 90000000 adrp x0, 400000 <_init-0x418>
400498: 9119c000 add x0, x0, #0x670
int main() {
40049c: 910003fd mov x29, sp
printf("Hello World!\n");
4004a0: 97fffff8 bl 400480 <printf@plt>
4004a4: 52800000 mov w0, #0x0 // #0
4004a8: a8c17bfd ldp x29, x30, [sp], #16
4004ac: d65f03c0 ret
#include <stdio.h>
int main() {
400490: a9bf7bfd stp x29, x30, [sp, #-16]!
printf("Hello World!\n");
400494: 90000000 adrp x0, 400000 <_init-0x418>
400498: 9119c000 add x0, x0, #0x670
int main() {
40049c: 910003fd mov x29, sp
printf("Hello World!\n");
4004a0: 97fffff8 bl 400480 <printf@plt>
4004a4: 52800000 mov w0, #0x0 // #0
4004a8: a8c17bfd ldp x29, x30, [sp], #16
4004ac: d65f03c0 ret
No comments:
Post a Comment