qidao123.com技术社区-IT企服评测·应用市场
标题:
【C语言编译】编译原理和详细过程
[打印本页]
作者:
三尺非寒
时间:
2025-5-6 22:46
标题:
【C语言编译】编译原理和详细过程
1. C 语言编译原理和详细过程
编译是将源代码转换为盘算机可实行的二进制文件的过程,整个过程主要分为四个阶段:
预处理处罚; 编译; 汇编; 链接
。
1.1 预处理处罚阶段
工具:预处理处罚器
输入:.c 源文件
输出:.i 预处理处罚后的文件
预处理处罚阶段做的主要工作:
宏睁开
:将全部#define界说的宏进行文本替换
头文件包罗
:递归睁开#include指令,将头文件内容
插入源代码
条件编译
:处理处罚条件编译指令(如#ifdef等命令),根据条件保留或删除代码块(如调试代码)
删除注释
1.2 编译阶段
工具:编译器
输入:.i文件
输出:.s汇编代码文件
编译阶段做的主要工作:
词法分析
:将代码拆分为token(如标识符,关键字,运算符)
语法分析
:构建抽象语法树(AST),检查语法是否符合C标准(如检查括号是否匹配,语句是否合法)
语义分析
:检查类型匹配,变量声明,作用域规则
中间代码生成
:生成与平台无关的中间体现(如三地点码)
代码优化
:对中间代码进行优化。如删除冗余代码、常量折叠等
目标代码生成
:将优化后的中间代码转换为
目标平台的汇编代码
1.3 汇编阶段
工具:汇编器
输入:.s汇编文件
输出:.o目标文件,即二进制呆板码
汇编阶段做的主要工作:
指令转换
:将汇编代码逐行转换为呆板码
生成目标文件
:生成包罗呆板码、符号表、重定位信息的**.o文件**
1.4 链接阶段
工具:链接器
输入:多个.o目标文件+静态库.a文件
输出:可实行文件
链接阶段做的主要工作:
符号剖析
:解决跨文件的函数或变量引用。如main.o中调用printf函数,则需找到该函数在libc.a中的界说
重定位
:合并全部目标文件的代码段、数据段,分配最终内存地点;修正符号表中的地点偏移量
库文件处理处罚
:
- 静态链接:将静态库.a代码直接
复制
到可实行文件中
- 动态链接:记载动态库.so的路径,
运行时加载
生成可实行文件
:生成符合操纵体系格式的可实行文件
注:可实行文件分为
代码段(.text)、数据段(.data)、未初始化数据段(.bss)
等
经过这一系列过程,c源代码最终变成了操纵体系可直接实行的二进制文件 运行时由加载器将其读入内存并实行。
2. 疑问点剖析
2.1 三地点码是什么?有什么作用
三地点码(Three-Address Code,TAC)是
编译器中常用的一种中间体现(Intermediate Representation, IR)情势
,它将复杂的表达式和语句拆解为一系列简单的指令,每条指令最多包罗三个操纵数。它的核心目标是简化代码优化和目标代码生成的过程,同时保持与呆板无关的特性。
每条指令仅包罗一个操纵(如赋值,运算,跳转等),最多涉及三个操纵数,两个输入一个输出。常见的通用格式如下:
result = operand1 op operand2
复制代码
2.2 符号表是什么?有何作用
符号表是编译器/汇编器生成的一种数据布局,记载了步伐中全部符号的信息:
符号名称:如函数名、全局变量名称;
符号类型:函数、变量、静态/全局作用域等;
符号地点:在目标文件中的相对地点或内存地点。
符号分类:
全局符号:可被其他文件访问的符号,如extern变量、非static函数;
局部符号:仅在本文件内可见的符号,如static函数或变量;
外部符号:在本文件中使用但未界说的符号,如调用了其他文件中的函数。
在链接阶段,链接器通过符号表剖析不同目标文件之间的符号引用,如函数调用、变量访问等;符号表包罗了符号的地点和类型,支持调试器(如gdb)定位代码和变量(比如有时间调试的时间会导入符号表);动态链接库.so必要依赖符号表在运行时绑定函数地点。
2.3 重定位的含义与作用
重定位时链接器在合并多个目标文件时,
修正符号引用地点的过程
。目标文件.o中的代码和数据地点是临时地点(基于偏移量的),链接器必要将其调解为最终可实行文件的绝对地点。
重定位表
:每个目标文件都有一个重定位表,记载了必要修正的位置及其规则:
必要修正的偏移量:在目标文件中的位置;
符号名称:必要修正为哪个符号的地点;
重定位类型:怎样盘算最终地点,如相对地点或绝对地点。
重定位的作用:
合并多目标文件:将分散在多个.o文件中的代码和数据分配到同一的内存布局中;
剖析外部依赖:将未界说的符号绑定到库中的实际地点;
生成可实行文件:确保步伐运行时,全部指令和数据的地点准确。
2.3 符号表和重定位在整个编译过程中的作用
编译阶段会生成符号表并记载重定位信息:
生成符号表:编译器为每个.c文件生成.o目标文件,包罗符号表和代码;
记载重定位信息:编译器标记全部必要重定位的位置,如外部函数调用等。
链接阶段会进行符号剖析以及地点分配与重定位:
符号剖析:链接器会检查全部目标文件的符号表,确保每个符号有且仅有一个界说;
地点分配与重定位:链接器为全部符号分配最终地点,并修正代码中的引用。
即符号表是步伐符号的
地点簿
,记载了
符号的界说和引用
;重定位是链接器的
修正工具
,确保步伐可以准确访问全部符号。
2.4 动态链接库.so和静态链接库.a
动态链接库.so文件,是在
步伐运行时
被加载的,多个步伐可
共享
同一个库文件,节省内存和磁盘空间。
静态链接库.a文件,是在
编译时
被
整合到
可实行文件中,生成
独立的
可实行文件,不必要外部依赖。
静态链接库和动态链接库的主要区别:
特性
静态库(.a)
动态库(.so)
链接方式
编译时
直接嵌入
到可实行文件中步伐运行时
动态加载
文件体积
可实行文件
体积较大
(包罗库代码)可实行文件
体积较小
(仅存引用)
运行时依赖
无需外部库文件必须存在对应的.so文件
内存占用
每个历程独立加载库代码,
内存冗余
多个历程共享同一份库代码,
内存节省
更新维护
需重新编译整个步伐仅替换.so文件即可更新库功能
加载速度
启动快(代码已嵌入)启动稍慢(需加载动态库)
兼容性风险
无版本冲突问题需包管.so版本与步伐兼容
常见使用场景
嵌入式体系、独立工具、无依赖部署通用体系库(如libc)、多历程共享场景
示例:
静态链接:
gcc main.c -o program -L/path/to/libs -lstaticlib -static
复制代码
-static选项表明欺压静态链接全部库,包括库体系如libc
这样生成的program不依赖任何外部库。
动态链接:
gcc main.c -o program -L/path/to/libs -ldynamiclib
复制代码
默认链接动态库(优先查找.so),运行时需确保动态库在体系路径或通过LD_LIBRARY_PATH指定。
混合链接:
gcc main.c -o program -Wl,-Bstatic -lstaticlib -Wl,-Bdynamic -ldynamiclib
复制代码
-Wl,-Bstatic:指定后续库静态链接。
-Wl,-Bdynamic:规复为动态链接
2.5 不要肴杂.o文件和.so文件
.o文件是目标文件,
通常是编译单个源文件后的输出
,包罗呆板码和符号表,但还未经过链接,以是
可能有未剖析的符号
。
.so文件是动态链接库,
是多个目标文件经过链接后生成的共享库
,可以在运行时被多个步伐共享。
.o文件是编译阶段的产物,.so文件是链接阶段的产物;.so文件在步伐运行时加载,.o文件在链接时被合并到可实行文件或静态库中。
二者主要区别:
特性
目标文件(.o)
动态链接库(.so)
生成阶段
编译阶段
的产物(单个源文件编译后生成)
链接阶段
的产物(多个目标文件或源码链接生成)
内容
包罗
单个源文件编译后的呆板码
、符号表、重定位信息包罗
多个目标文件或源码的已链接代码
,具有完整的符号剖析和地点分配
用途
作为中间文件,供后续链接生成可实行文件或库作为共享库,供步伐在
运行时动态加载
依赖关系
未剖析的符号需在链接阶段解决符号已完全剖析,但需在运行时与主步伐或其他库动态绑定
文件独立性
无法单独运行,需链接后使用可独立存在,但需主步伐调用或动态加载
内存共享
不共享,每个历程独立加载多个历程可共享同一份.so的代码段,节省内存
更新维护
修改后需重新编译和链接更新.so后,主步伐无需重新编译(需接口兼容) .o文件,通过
编译
单个源文件生成,包罗呆板码、符号表和重定位信息。.o文件作为中间文件,以供后续链接器将全部.o文件合并为可实行文件或库(可被归档为静态库.a文件,本质上是多个.o的聚集)
.so文件,通过
链接
多个目标文件或源码生成,包罗完全链接的代码(全部的符号已剖析,除非依赖其他动态库)、位置无关代码(代码可加载到恣意内存地点运行)、导出符号表(声明库中可供外部调用的函数或变量)。.so文件是在步伐运行时由动态链接器加载到内存的,多个步伐可共享一份.so代码,减少内存占用,同时支持库的热更新(即替换.so文件后重启步伐见效)
总结:
.o文件
是编译阶段的中间产物,用于后续链接;
.so文件
是
链接后
的动态库,用于运行时共享。
.o文件聚焦单个模块的编译结果,.so文件聚焦多模块的协作与动态加载。
3. 知识补充
【GCC】gcc编译学习
【GDB】gdb使用
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/)
Powered by Discuz! X3.4