当前位置: 首页 > news >正文

编译和链接

预处理:处理原文件中以#开头开始的预编译指令

展开所有的宏定义,#define

l 处理所有的条件预编译指令,#ifdef

l 处理#include预编译指令,递归进行

删除所有的注释

添加行号和文件名标识

l 保留所有的#pragma编译器指令

编译:预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后产生相应的汇编代码文件

汇编汇编代码转变成机器可以执行的指令

链接

编译器做了什么?

编译过程:

源代码---扫描器--->符号----解析器----->语法树----语义分析--->标注语法树---源代码优化--->中间代码生成---代码生成器---->目标代码---代码优化器---->最终代码

词法分析——运用一种类似于有限状态机的算法将源代码字符分割成一系列的记号(Token),其中记号分为关键字、标识符、字面量(常数、字符串等)和特殊符号(运算符号等)这几类。进行词法分析的工具为lex 

语法分析——采用上下文无关语法,生成以表达式为节点,以常数和标识符最基层叶子的语法树,完成高级语言的语法分析。进行语法分析的现成工具为yacc,根据用户给定的语法规则对输入的记号序列进行解析,因此使用yacc可以针对不同的编程语言,只需改变规则就可以得到相应的语法分析器

语义分析——语法分析仅仅完成了源代码的语法层面的分析,但是对于表达式是否有意义,是否合法并不清楚,这就需要进行表达式的语义分析,并完成一些潜在的类型转换、匹配等。完成语义分析后,语法树的每一个表达式都被标识了相应的类型,如果有些类型需要隐式转化,必须插入相应的转换节点

中间语言生成——将整个语法树转换为与硬件无关的中间代码。常见的中间代码类型为“三地址码”,形如 x = y op z 。中间代码的存在使得整个编译器软件被分为了与硬件无关的前端和与硬件相关的后端,这就使得编译器可以支持多种编程语言的编译工作,使用相同的前端,需要改变的仅仅只是后端而已

目标代码生成与优化——根据特定硬件的字长、寄存器、指令集等特性,将中间代码生成相应的汇编语言代码

链接器

现代软件规模非常庞大,因此软件的分模块成为了必然的趋势,各个模块代码被单独编译得到目标文件然后将这些模块组装到一起成为一个可执行文件,就是链接器的工作,其主要内容其实就是将各个模块之间的相互引用处理好,将一些指令对在其他模块定义的符号的引用进行地址的修正

仅仅通过编译得到的目标文件中存在着很多的重定位入口,即不能确定物理地址的符号在未经链接的目标文件中这些符号的物理地址往往都被置为0,需要由链接器来对其进行修正——即重定位

C++模块通信的两种方式

l 模块间的函数调用

l 模块间的变量访问

这两种方式都归结为一种,就是模块间的引用

链接的主要内容就是把各个模块之间相互引用的部分都处理好,各个模块之间能够正确地衔接。

链接的过程包括了地址和空间分配、符号决议(符号绑定)、重定位

所谓的库文件可以理解为一组常用代码编译得到的目标文件的打包,最常见的库就是运行时库,是支持程序运行的基本函数的集合。静态链接的过程就是将多个目标文件与库文件进行链接得到可执行文件的过程。

相关文章:

  • 目标文件里有什么?
  • JS setTimeout和setInterval的区别
  • JavaScript 变量提升
  • JavaScript 调试
  • JavaScript 库(框架)
  • Cefsharp js调用c#与c#调用js
  • JavaScript之Window 对象
  • javascript之Navigator 对象
  • javascript之Screen 对象
  • javascript之History 对象
  • JavaScript之Location 对象
  • JavaScript 存储对象
  • 寻址 far near
  • Session原理
  • DOM选择器
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • canvas绘制圆角头像
  • Debian下无root权限使用Python访问Oracle
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • Java读取Properties文件的六种方法
  • Map集合、散列表、红黑树介绍
  • Nacos系列:Nacos的Java SDK使用
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • vagrant 添加本地 box 安装 laravel homestead
  • 关于Flux,Vuex,Redux的思考
  • 如何进阶一名有竞争力的程序员?
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • !! 2.对十份论文和报告中的关于OpenCV和Android NDK开发的总结
  • !!Dom4j 学习笔记
  • #include
  • #Linux(帮助手册)
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (03)光刻——半导体电路的绘制
  • (Matlab)使用竞争神经网络实现数据聚类
  • (poj1.2.1)1970(筛选法模拟)
  • (ros//EnvironmentVariables)ros环境变量
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (五)关系数据库标准语言SQL
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转) Android中ViewStub组件使用
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .apk 成为历史!
  • .NET : 在VS2008中计算代码度量值
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法
  • .Net的C#语言取月份数值对应的MonthName值
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • .NET微信公众号开发-2.0创建自定义菜单
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件