程序员的自我修养-前三章思维导图
2021-05-07 17:11:36 9 举报
AI智能生成
前三章思维导图
作者其他创作
大纲/内容
编译和链接
程序的构建
预处理-编译-汇编-链接
预处理
展开宏定义
编译
流程:源代码—词法分析→记号—语法分析→语法树—语义分析→注释语法树—源代码优化→中间代码
源代码
记号
扫描器通过词法分析将源代码分割成记号
语法树
语法分析器通过语法分析将记号转换成语法树
def:以表达式为节点的树
注释语法树
语法树通过语义分析转换成注释语法树
中间代码
将转换后的语法树进行优化
从源代码到中间代码过程为编译器前端,中间代码到目标代码为编译器后端
目标代码
由中间代码转换而来的目标机器码
最终目标代码
将目标机器码进行优化得到
汇编
将汇编代码转换为机械指令
链接
地址和空间分配
符号决议
重定位
目标文件
可执行文件格式
Windows:PE-COFF
Linux:ELF
可重定位文件
可执行文件(直接执行的程序)
共享目标文件
核心转储文件
ELF文件格式
ELF Header
描述文件属性和存储段表
.text
代码段
.data
数据段
.bss
未初始化的全局/局部静态变量
不占用文件空间,但在装载时占用地址空间
ELF结构
.shstrtab
段表字符串表
保存段表中用到的字符串
段表:保存存储段的相关属性,描述段的基本信息
.symtab
符号表
def:记录目标文件用到的函数和变量
符号:连接过程中用到的函数和变量
符号值:定义的符号有一个对应的值,这个值就是他们的地址
.rel.text
重定位表
每一个需要重定位的代码段或数据段都有对应的段表,rel.text就是text段的重定位表
符号修饰与函数签名:为了防止符号名冲突
C++的符号修饰与签名
C++使用了名称空间和重载解决多模块符号冲突的问题
C++和C的兼容
C++以"extern C"关键字实现对C的兼容,在关键字修饰内的代码以C处理
弱符号与强符号
弱符号
def:未初始化的全局变量
强符号
def:编译器默认函数和已初始化的全局变量
弱引用和强引用
调试信息
strip 函数名 去掉调试信息节约空间
调试信息占据大量空间
静态链接
链接过程
空间和地址分配
按序叠加
段段对齐,浪费空间
相似段合并
这里的空间分配只对于虚拟地址的的分配
确定虚拟地址的分配及偏移量
符号解析和重定位
链接器通过符号地址及重定位表对重定位指令进行修正
确定重定位符号引用的目标地址,在全局符号表中查询重定位
指令修正方式
绝对寻址修正
相对寻址修正
COMMON块
目的:解决弱符号类型不一致的问题,还避免了与强符号发生符号重复定义错误
因为弱符号所占空间大小在编译的时候是未知的,所以无法分配空间,只能标记为common类型
在链接时确定其大小,在.bss段为其分配空间
C++的特殊
C++的重复代码消除
把每个模板实例都单独存放在一个段中,每个段只包含一个模板实例
函数级别链接
全局构造与析构
.init
发生在main之前,包含初始化代码指令
.finl
发生在main之后,包含终止代码指令
二进制兼容问题
将目标文件的各信息做统一规定,叫做ABI,二进制兼容标准
C++ABI目前还未统一
静态库链接
静态库:一组目标文件的集合
1.将源代码编译成临时汇编文件
2.将临时汇编文件汇编成临时目标文件
3.调用ld链接器完成对目标文件的链接并处理
链接过程的控制
链接控制
使用命令行给链接器指定参数
将链接指令存放在目标文件中
使用链接控制脚本
ld链接脚本
ld链接脚本语法
BFD库
通过一个统一的接口处理不同的目标文件格式
收藏
收藏
0 条评论
下一页