gcc 编译流程
来源:互联网 发布:软件测试教程学习 编辑:程序博客网 时间:2024/06/05 20:07
gcc编译流程分为四个步骤:
1:预编译处理 :主要是进行宏替换和拷贝包含的头文件到本文件
2:编译: 检查代码的规范性,是否有语法错误等,没错的话将代码编译成汇编语言
3:汇编:将汇编文件转换成二进制目标文件
4:链接:链接库函数生成可执行文件
详解如下:
一:用C语言编写一个简单的程序,文件名为main.c,内容如下
#include<stdio.h>
#define MAX(x,y) (x) > (y) ? (x) : (y)
#define MIX(x,y) (x) < (y) ? (x) : (y)
#define MAXIMUM
int main()
{
int a = 0;
int x = 3;
int y = 5;
#ifdef MAXIMUM
a = MAX(x,y);
#else
a = MIN(x,y);
#endif
printf("a = %d\n", a);
return 0;
}
二:执行 gcc -E main.c -o main.i(预处理)
打开main.i 可以看到头文件stdio.h被加载进来了,同时main函数里面的宏定义被替换了
三:编译:在这个阶段中,GCC首先要检查代码的规范性,是否有语法错误等,以确定代码实际要做的工作,检查无误后,GCC将代码翻译成汇编语言,命令如下:gcc -S main.i -o main.s
main.s的内容是汇编语言,内容如下:
1 .file "main.c"
2 .section .rodata
3 .LC0:
4 .string "a = %d\n"
5 .text
6 .globl main
7 .type main, @function
8 main:
9 .LFB0:
10 .cfi_startproc
11 pushq %rbp
12 .cfi_def_cfa_offset 16
13 .cfi_offset 6, -16
14 movq %rsp, %rbp
15 .cfi_def_cfa_register 6
16 subq $16, %rsp
17 movl $0, -12(%rbp)
18 movl $3, -8(%rbp)
19 movl $5, -4(%rbp)
20 movl -8(%rbp), %eax
21 cmpl %eax, -4(%rbp)
22 cmovge -4(%rbp), %eax
23 movl %eax, -12(%rbp)
24 movl -12(%rbp), %eax
25 movl %eax, %esi
26 movl $.LC0, %edi
27 movl $0, %eax
28 call printf
29 movl $0, %eax
30 leave
31 .cfi_def_cfa 7, 8
32 ret
33 .cfi_endproc
34 .LFE0:
35 .size main, .-main
36 .ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
37 .section .note.GNU-stack,"",@progbits
四:汇编.汇编阶段就是把编译阶段生成的.s文件转换成目标文件,命令如下:gcc -c main.s -o main.o
五:链接:汇编阶段生成的二进制目标文件并不是可执行程序,例如,main函数里面用到的printf函数并没有实现,有人会问,#include<stdio.h>不是已经实现了吗,不是的,在预处理阶段,包含的stdio.h只有该函数的声明,并没有定义printf函数的实现,其实系统会把stdio.h的函数实现都加在libc.so.6的库文件中,在没有特别的指定时,GCC会到系统默认的搜索路径/usr/lib下进行查找,也就是链接到libc.so.6库函数中,这样就可以实现函数printf了,这也就是链接的作用.
命令:gcc main.o -o main
静态库和动态库
库函数一般分为静态库和动态库两种.静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了.其后缀名一般为.a.动态库与静态库相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由链接文件加载库,这样可以节省系统的存储空间,避免重复装载相同的库到内存.动态库一般后缀名为.so ,如前面所述的libc.so.6就是动态库.
ps:以上内容参考教科书<ARM嵌入式Linux应用开发入门>------汪明虎 欧文盛编著,如有侵权,请联系我删除,谢谢!!!
- 【gcc】gcc的编译流程
- gcc编译流程
- GCC编译流程
- Gcc编译流程解析
- GCC编译流程
- GCC编译流程分析
- GCC的编译流程
- GCC的编译流程
- Gcc编译流程解析
- Gcc编译流程解析
- gcc的编译流程
- GCC编译流程分析
- gcc 编译流程
- gcc 编译流程
- 转-Gcc编译流程解析
- GCC的编译流程详解
- 【Linux基础】Gcc编译流程
- GCC编译简单流程---汇总
- 详解CMS垃圾回收机制
- 蓝桥杯:大臣的旅费(一般方法)
- linux命令深度使用 – ls
- 关于数据传输安全(SSH协议)
- zoj2112 Dynamic Rankings(整体二分+树状数组)
- gcc 编译流程
- Ubuntu安装Flink-1.4.0
- hbase基本操作---修改表的列簇
- NYOJ-32-组合数
- 20170707
- PageRank算法
- 封装一个提取url参数的小方法
- 正则表达式的切割 查找 替换
- Eclipse导入JavaWeb项目报错:The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build