C语言-程序预处理、编译、链接详解(一)

简介: C语言-程序预处理、编译、链接详解

程序的翻译环境

在ANSI C的实现中,存在两个不同的环境:翻译环境和执行环境。

翻译环境中源代码被转换为可执行的机器指令,执行环境用于实际执行代码。

翻译环境:

链接库:调用某一个函数时,会把和该函数相关的几个库一起链接进去。

组成一个程序的每个源文件通过编译过程分别转换成目标代码,每个目标文件由链接器捆绑在一起,形成一个单一而完整的可执行程序,链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序中。


编译阶段

在CentOS上写如下test.c程序:

(1)预处理阶段:

执行gcc test.c -E>test.i

执行vim test.i查看.i文件,滚动到底部可以看到红色框内的代码,前面都是预处理时替换的内容,MAX(a,b)也被替换为((100)>(200)?(100):(200)),且注释不见了。

 以蓝色框内flockfile、ftrylockfile、funlockfile函数为例查看预处理时是如何替换库函数的:查看/usr/include/下的头文件

vim 查看stdio.h文件,滚动到底部,可以看到flockfile、ftrylockfile、funlockfile函数,预处理使用stdio.h的内容将#include<stdio.h>替换了

这说明执行gcc test.c -E>test.i做了3件事:1.完成头文件的包含,2#define定义的宏的替换,3.删除注释。

(2)编译阶段

执行gcc test.i -S

vim test.s,可以看到里面都是汇编代码

编译阶段主要把C语言代码转化成汇编代码,包括语法分析、词法分析、语义分析、符号汇总。

(3)汇编阶段

执行gcc test.s -c,生成test.o文件

test.o文件时elf格式的,使用readelf工具查看,执行readelf test.o -s查看test.o文件,生成的符号名有g_val、Add、main、printf分别对应源文件的全局变量和函数。

汇编阶段把汇编代码转换成机器指令(二进制指令)生成目标文件,形成符号表。


链接阶段

将test.c中Add函数的执行放在add.c文件中:

test.c

add.c

编译成目标文件,查看目标文件:

test.o

add.o

可以看到test.o和add.o中的符号表都包含Add,但是test.o中的Add函数没有意义,只是声明而已。在链接阶段会合并段表,并进行符号表的合并和重定位。

编译链接阶段的执行过程:


相关文章
|
1月前
|
存储 自然语言处理 编译器
【C语言】编译与链接:深入理解程序构建过程
【C语言】编译与链接:深入理解程序构建过程
|
30天前
|
编译器 C语言
C语言--预处理详解(1)
【10月更文挑战第3天】
|
30天前
|
编译器 Linux C语言
C语言--预处理详解(3)
【10月更文挑战第3天】
|
8天前
|
C语言
【c语言】你绝对没见过的预处理技巧
本文介绍了C语言中预处理(预编译)的相关知识和指令,包括预定义符号、`#define`定义常量和宏、宏与函数的对比、`#`和`##`操作符、`#undef`撤销宏定义、条件编译以及头文件的包含方式。通过具体示例详细解释了各指令的使用方法和注意事项,帮助读者更好地理解和应用预处理技术。
17 2
|
30天前
|
存储 自然语言处理 编译器
|
29天前
|
自然语言处理 编译器 Linux
C语言中抽象的编译和链接原理
C语言中抽象的编译和链接原理
20 1
|
30天前
|
C语言
C语言--预处理详解(2)
【10月更文挑战第3天】
|
27天前
|
存储 文件存储 C语言
深入C语言:文件操作实现局外影响程序
深入C语言:文件操作实现局外影响程序
|
1月前
|
编译器 C语言
C语言预处理详解
C语言预处理详解
|
26天前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
31 3