程序员的自我修养(2)----静态链接

程序员的自我修养(2)—-静态链接

本章介绍,静态链接的过程,首先总体介绍了,四个基本步骤,预编译,编译,汇编,链接,接着详细介绍了每个过程做了什么,以及如何做到的.

Created with Raphaël 2.1.0 start source file 预编译 ".i"文件 编译 汇编代码文件 汇编 中间目标文件(".o") 链接 可执行文件(".out") end
1 预编译

预编译过程很简单,就是一些简单的预处理过程,我们使用的宏和条件预编译指令都在这个阶段被处理.

  • 将宏展开 即替换所有#define 定义的宏
  • 处理#if #else #elif等预编译处理命令,删除掉,不需要编译的代码
  • 处理#include 将,包含的头文件递归,插入到该语句坐在的位置
  • 删除所有注释

最后生成”.i”文件

2 编译

编译过程简单来说就是,将预处理完的”.i”文件经过
词法分析—->语法分析—->语义分析及优化—->汇编代码文件

2.1 词法分析

源代码输入扫描器,就源代码分割成一系列的记号,有如下几类:关键字 标识符 字面量(数字 字符串等) 特殊符号(加号 减号)

2.2 语法分析

对词法分析产生的记号进行语法分析,按照符号表达式的优先级生成语法树,符号和数字树语法树的叶子节点.

2.3 语义分析

编译器只能做到静态语义分析,包括,声明和类型匹配和转换,语义分析会对,语法书的每个表达式标识类型.

2.4 中间代码生成

这里生成最接近目标代码的中间代码,例如三字节码,中间代码还是与目标机器无关的,编译器其实分为前端和后端,前端负责生成与目标机器无关的代码,后端根据机器生成目标机器代码,不同的硬件机器代码标准不一样,跨平台的编译器,就是一个前端,和多个不同的后端来组成.

2.5 目标代码生成和优化

现在的编译器优化非常复杂,,举个例子,常量的相加,可以非常方便的直接优化,具体的优化细节这里不讲,这一步就是编译器的后端部分了,他会生成目标机器代码,也就是汇编代码,就是mov jmp之类的.这里有一个问题,一个项目是分模块的,A模块用的B模块的变量和函数等,编译器对每个模块是单独编译的,那么编译A模块的时候,这个时候是不知道使用B中的函数foo_B的地址的,怎么在汇编代码中表示呢?这就是后面要讲的链接要解决的事情了.

3 汇编

汇编这个操作也很简单,就是根据机器将汇编代码按照汇编代码与机器码对应的一个表,一个个将汇编代码映射为机器码的过程.

4 链接

回到刚才2.5中提出的问题,因为工程复杂,各个工能模块有自己的实现函数和接口,其他模块调用的时候并不知道调用的函数的地址的,这里采取的解决方案,就是在这些不知道地址的地方,放上一个标记,这个标记就是表示,这个地方会在链接的时候进行替换,替换为调用模块中那个函数实际的地址,这个过程叫做重定位,举个例子,就是调用其他模块的地方留出一个坑,链接的时候,就拿正确的东西来填这个坑.

5 静态链接

回到本章主题,静态链接,主要工作如下
1. 地址和空间分配:给每个函数和变量分配地址
2 .符号决议:我的理解是给每个函数和变量命名为独一无二可区分的符号
3. 重定位:就是更新函数中用到的函数对应的地址,就是第一条中所分配的地址
注意,在静态链接前,各个模块引用其他模块的函数或者变量,是可以不关注定义的,只需要包含其他模块的头文件,而静态库.a就是多个.o文件的集合,这样的静态库也是合法的,但是在链接(包括静态链接和动态链接)的过程中,如果之前应用的函数或者变量没有找到定义,会报错某某函数或者变量未定义错误!(静态库一定要链接成功之后才能保证可用)

本章结束,时间不够,要更加好好的利用时间,不要浪费时间!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值