当前位置:网站首页>GCC related

GCC related

2022-06-25 11:04:00 Jacob_ Always

GCC: GNU Compiler Collection
namely GNU Compiler Suite , It belongs to a programming language compiler , Its original name was GCC (GNU C Compiler) namely GNU C Language compiler , Although the abbreviations are the same, the functions are very different .GCC The original intention is to GNU A compiler specially written by the operating system , The original GNU Is specifically used to compile C Code , Now it has been extended to compile C、C++、Java、Objective-C And other programming languages .

GCC、gcc、g++ What is the relationship between the three Bold style
gcc yes GCC Medium C compiler , and g++ yes GCC Medium C++ compiler .
gcc and g++ Both can be compiled c and cpp file , But there are differences .gcc Compiling cpp The grammar is in accordance with c To compile the , But it cannot be linked to by default C++ library (gcc Default link c library ,g++ Default link c++ library ).g++ compile c and cpp All the documents are unified according to cpp Syntax rules to compile .

gcc Common instructions
gcc At compile time Not generated directly .out file , In the process, it also goes through pretreatment 、 compile 、 Assemble and connect several processes .

Source code :

#include <stdio.h>
#include "elf_Hello.h"

void main()
{
    
	int i = JACOB;
	DoNothing();
	CALC
	return;
}
[[email protected] elf_file]# cat elf_Hello.h
#define JACOB 1000
#define CALC printf("Hello");
void DoNothing(void);
  • Instructions :-o

Instructions -o Will be used to specify the generated file name :

[[email protected] elf_file]# gcc elf_Hello.c -o elf_Hello
[[email protected] elf_file]# ll
total 8
-rwxr-xr-x 1 root root   0 Apr 29 17:21 elf_Hello
-rw-r--r-- 1 root root 104 Apr 29 17:17 elf_Hello.c
-rw-r--r-- 1 root root  71 Apr 29 16:35 elf_Hello.h
[[email protected] elf_file]#

- Instructions : -E( Preprocessing Preprocessing)
Instructions -E( Capitalization ) The preprocessing operation will be performed , Generation *.i file ,gcc The compiler will be on # The first instruction is parsed .

[[email protected] elf_file]# cat elf_Hello.h
#define JACOB 1000
#define CALC printf("Hello");
void DoNothing(void);
[[email protected] elf_file]# cat elf_Hello.c
#include <stdio.h>
#include "elf_Hello.h"

void main()
{
    
	int i = JACOB;
	DoNothing();
	CALC
	return;
}

stay elf_Hello.c The file needs to include the calling header file , Replace macro constants and macro code snippets .
Carry out orders :gcc -E elf_Hello.c -o elf_Hello.i

[[email protected] elf_file]# gcc -E elf_Hello.c -o elf_Hello.i
[[email protected] elf_file]# cat elf_Nothing.i
...
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 943 "/usr/include/stdio.h" 3 4

# 2 "elf_Hello.c" 2
# 1 "elf_Hello.h" 1


void DoNothing(void);
# 3 "elf_Hello.c" 2

void main()
{
    
 int i = 1000;
 DoNothing();
 printf("Hello");
 return;
}

All comments are removed in the preprocessing stage
from elf_Hello.i The document shows that , Header files are included , The declarative part of the function , Macro constants are replaced , Macro code snippet is replaced .

 Command enable gcc Perform preprocessing , For pretreatment # Class instructions ( Include header file 、 Replace macro constants and macro code snippets ), It is not difficult to understand why elf_Hello.i The file will be big , The whole project is finally crumpled into a big file . Preprocessing removes all comments , So the decompiled code is uncommented ! Because the comments have long been removed . Another thing that can be mentioned is the use of instructions gcc -E elf_Hello.c When the output file name is not specified, the content will be output directly to the command line , Without generating files .

The preprocessing phase does not check for syntax errors ;

[[email protected] elf_file]# gcc -E elf_Hello.c
...
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 943 "/usr/include/stdio.h" 3 4

# 2 "elf_Hello.c" 2
# 1 "elf_Hello.h" 1


void DoNothing(void);
# 3 "elf_Hello.c" 2

void main()
{
    
 int i = 1000;
 DoNothing();
 printf("Hello");
 return;
}

- Instructions : -S( compile Compiling)
perform -S( Capitalization ) Instructions will be *.i File source code into assembly code *.s file . We carry out instructions gcc -S elf_Hello.i -o elf_Hello.s, In the current directory, will generate elf_Nothing.s file , Open it with notepad and you will find c The source code has been converted into assembly code by the compiler .

[[email protected] elf_file]# gcc -S elf_Hello.i -o elf_Hello.s
[[email protected] elf_file]# cat elf_Hello.s
	.file	"elf_Hello.c"
	.section	.rodata
.LC0:
	.string	"Hello"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	$1000, -4(%rbp)
	call	DoNothing
	movl	$.LC0, %edi
	movl	$0, %eax
	call	printf
	nop
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.8.2 20140120 (Red Hat 4.8.2-16)"
	.section	.note.GNU-stack,"",@progbits

If you use instructions gcc -S elf_Hello.i That is, the output file name is not specified , By default, files will also be generated in the current directory elf_Hello.s
The syntax check is performed during the recompile phase .

- Instructions : -c( assembly Assembling)
perform -c( A lowercase letter ) Instructions will be *.s The assembly source code in the file converts the binary machine code that can not be executed by the machine , Generate the file .o*. Execution instruction gcc -c elf_Hello.s -o elf_Hello.o. Generated elf_Hello.o For binary , When you open it with Notepad, it is a pile of garbled code .

[[email protected] elf_file]# gcc -c elf_Hello.s -o elf_Hello.o
[[email protected] elf_file]# cat elf_Hello.o ELF> 恀 @
UH䈃ꑇE𨿸 Leaves elloGCC: (GNU) 4.8.2 20140120 (Red Hat 4.8.2-16)zRx
a                                                           C
&elf_Hello.cmainDoNothingprintf
񁀿ÿÿ

񁀿ÿÿ .symtab.strtab.shstrtab.rela.text.data.bss.rodata.comment.note.GNU-stack.rela.eh_frame @& H                                                                                                                                                    &ff1f90l.BW [email protected]                                                                                                                                                                                                                                    ֠

- Instructions : gcc .o( link Linking)
Binary files generated after assembly processing elf_Hello.o Although the machine code , But it still can't run because there is no link operation . Link operation executable instructions
gcc elf_Hello.o -o elf_Hello*.

[[email protected] elf_file]# gcc elf_Hello.o -o elf_Hello
elf_Hello.o: In function `main': elf_Hello.c:(.text+0x10): undefined reference to `DoNothing'
collect2: error: ld returned 1 exit status

Yes elf_Hello.o An error is reported when performing the link operation , Hint function not found DoNothing The definition of . Include the header file when preprocessing phase values elf_Hello.i In file , That is to say elf_Hello.i Contains the declaration part of the function , Therefore, the compilation stage only checks whether the declaration and call of the function conform to the function prototype , I didn't check the others *.c Function definition in file .
The link phase is to associate the function definitions in the function library , Of course, an error will be reported if the function definition is not found . So here comes the question , The standard library functions we call printf Why not report an error ? In fact, library functions are no exception , In the linking phase, you need to associate to the function definition , Its declaration part is in the standard library function header file stdio.h Given in , The implementation part is encapsulated in a standard library , There will be differences under different systems .gcc When linking, the default is to include the library file path of the standard library , So it can find printf The definition of the function without any error . and DoNothing The function is written by our users , Not encapsulated in a library gcc Of course, we can't find its definition .
In order to make elf_Hello.o Can successfully generate executable files elf_Hello, We can DoNothing() Functions are encapsulated into static libraries for them to call , So there is a function definition .

[[email protected] elf_file]# cat libDoNothing.c
#include <stdio.h>

void DoNothing()
{
    
	;
}

Execution instruction gcc -c libDoNothing.c -o DoNothing.o Generate DoNothing.o Binary . It's not unnecessary here elf_Hello.c Perform preprocessing and compilation operations , But the compiler did it for us . And then DoNothing.o Generate static library files libDoNothing.a.

[[email protected] elf_file]# **ar -rcs libDoNothing.a DoNothing.o**

Then try again to elf_Hello.o Perform link operation .

gcc elf_Hello.o libDoNothing.a -o elf_Hello
[[email protected] elf_file]# ./elf_Hello
Hello
原网站

版权声明
本文为[Jacob_ Always]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202200540428719.html