gcc编译器知识点整理

gcc编译器

gcc:GNU compile Collection。(GNU项目中符合ANSI C标准的编译系统,能够编译c,c++c,ObjectC等语言)

主要功能:

gcc可以为x86,ARM,MIPS等不同体系结构的硬件平台编译程序:

GCC可以编译C,C++,Pascal,Java等数十种高级语言 。

gcc使用格式:gcc [选项] [文件名]  [选项] [文件名]

Gcc常用命令:

gcc -c :对源文件进行编译或汇编

gcc -E :对源文件进行预处理

gcc -s :对源文件进行编译

gcc -v :显示编译阶段的命令

gcc -o file:输出目标文件file

 

gcc -w :屏蔽所有的警告信息

gcc -wall :显示所有类型的警告

gcc -Werror :出现任何警告信息就停止编译

编译系统本身是一种相当复杂的程序,编写甚至读懂这样的程序都是非常困难的。但 是从事嵌入式 Linux 应用的开发人员都应掌握编译系统的基本原理和工作流程。

 GCC 工作流程 在 C 程序的编译过程中,依次要进行预处理、编译、汇编、链接四个阶段。这里通过编 译 C 文件 test.c 来展示 GCC 的工作流程。 例如: l test.c #include

int main()

{

   printf(“Hello world!\n”);

   return 0;

} 1. 预处理阶段 由于在 test.c 中使用了头文件 stdio.h,所以 GCC 在编译时首先要把头文件 stdio.h 中的内容加载到 test.c 中的首部。 在 shell 中输入命令“gcc -E test.c -o test.i”。其中,参数 E 告诉 gcc 命令只进行 预编译,不做其他处理;参数 o 用来指明输出的文件名为 test.i。命令运行完毕后就会产 生一个名为 test.i 的文件。如下所示:

[root@localhost home]#gcc -E test.c -o test.i [root@localhost home]#ls

test.c test.i

test.i 文件的代码有一百多行,如下所示的是 test.i 文件的最后部分代码。

extern char *ctermid (char *__s) __attribute__ ((__nothrow__));

# 820 "/usr/include/stdio.h" 3 4

extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__));

 extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;

extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));

# 850 "/usr/include/stdio.h" 3 4

 

# 2 "test.c" 2

int main()

{

  printf(“Hello world!\n”);

  return 0;

} 2. 编译阶段 编译阶段是整个编译过程中最复杂的一个阶段。这里拿自然语言的翻译过程作个对比。 比如在把“I love China”翻译成中文前,需要依次完成以下几个步骤: 1)考察这个句子中每个单词的拼写是不是正确。 2)考察整个句子的语法(比如主谓宾、定状补的结构等)是不是正确。 3)考察整个句子的语义是不是正确。 只有以上三个步骤都正常通过了,才能保证句子被正确翻译。同样,高级编程语言的编 译阶段也必须实现这三个步骤。 1) 步骤 1 称为词法分析,主要负责检查关键字、标识符等是否正确。 2) 步骤 2 称为语法分析,主要负责检查程序中语句的语法是否正确。 3) 步骤 3 称为语义分析,主要负责检查程序中语句的逻辑意义是否正确。 在 shell 中输入命令“gcc -S test.i -o test.s”。其中,参数 S 告诉 gcc 命令只进行 编译,不做其他处理。命令运行完毕后就会产生一个名为 test.s 的汇编文件。如下所示: [root@localhost home]#gcc -S test.i -o test.s

[root@localhost home]#ls

test.c test.i

test.s 在学习使用汇编语言编程的时候,对照 C 文件和其汇编程序是很好的办法。如下所示的 是 test.s 的代码。  

.file "test.c"

 .section .rodata

.LC0:

 .string "Hello world!"

 .text

.globl main

 .type main, @function

main:

 leal 4(%esp), %ecx

 andl $-16, %esp

 pushl -4(%ecx)

 pushl %ebp

 movl %esp, %ebp

 pushl %ecx

 subl $4, %esp

 movl $.LC0, (%esp)

 call puts

 movl $0, %eax

 addl $4, %esp

 popl %ecx

 popl %ebp

 leal -4(%ecx), %esp

 ret

 .size main, .-main

 .ident "GCC: (GNU) 4.2.1"

 .section .note.GNU-stack,"",@progbits

 

注意,以上所示的汇编代码是针对 x86 平台的。 3. 汇编阶段 汇编阶段的任务是把汇编程序翻译成 CPU 可以识别的二进制文件,该文件又称为目标 文件。 在 shell 中输入命令“gcc -c test.s -o test.o”,其中,参数 c 告诉 gcc 命令只进 行汇编,不做其他处理。命令运行完毕后就会产生一个名为 test.o 的目标文件。如下所示:

[root@localhost home]#gcc -c test.s -o test.o [root@localhost home]#ls test.c test.i test.o test.s

 

在 Windows 系统中,目标文件的后缀是 obj。 4. 链接阶段 目标文件虽然已经可以被 CPU 直接识别,但是单个目标文件一般是无法运行的。原因 在于一个程序往往是由多个源文件组成的,每个源文件只对应一个目标文件。也许有人会问, test 程序不就只有一个源文件 test.c 吗,为什么也不能直接运行呢?原因是 test.c 使用 了 stdio.h 对应的库函数,所以必须要把 test.o 文件和函数库文件链接在一起才能运行。 链接阶段的任务就是把程序中所有的目标文件和所需的库文件都链接在一起,最终生 成一个可以直接运行的文件,称为可执行文件。 在 shell 中输入命令“gcc test.o -o test”,运行完毕后就会产生一个名为 test 的 可执行文件。输入命令“./test”执行该文件,就可以得到 test 文件的运行结果“Hello world!”。 如下所示:

[root@localhost home]#gcc test.o -o test

[root@localhost home]#./test Hello world!

 gcc 命令生成的可执行文件的有以下三种格式。 1)a.out(Assembler and Link editor output); 2)COFF(Common object file format); 3)ELF(Executable and linkable format);

其中,a.out 和 COFF 格式都是比较老的格式,现在 Linux 平台上可执行文件的主流格 式是 ELF。

 

 

你可能感兴趣的:(gcc编译器知识点整理)