C程序的编译

经过预处理后的源文件,退去一切包装,注释被删除,各种预处理命令也基本上被处理掉,剩下的就是原汁原味的C代码了。接下来的第二步,就开始进入编译阶段。编译阶段主要分两步:第一步,编译器调用一系列解析工具,去分析这些C代码,将C源文件编译为汇编文件;第二步,通过汇编器将汇编文件汇编成可重定位的目标文件。

从C文件到汇编文件

从C文件到汇编文件,其实就是从高级语言到低级语言的转换。通过前面的学习我们知道,一个汇编文件是以段为单位来组织程序的:代码段、数据段、BSS段等,各个段之间相互独立。我们可以使用AREA或.section伪操作来定义一个段。

看到这里,聪明又机智的你可能已经发现:汇编程序的组织结构和二进制目标文件已经很接近了。没错,两者本质上其实就是等价的,汇编指令就是二进制指令的助记符,唯一的差异就是汇编语言的程序结构需要使用各种伪操作来组织。汇编文件经过汇编器汇编后,处理掉各种伪操作命令,就是二进制目标文件了。

从C源文件到汇编文件的转换,其实就是将C文件中的程序代码块、函数转换为汇编程序中的代码段,将C程序中的全局变量、静态变量、常量转换为汇编程序中的数据段、只读数据段。道理很简单,但真正实现起来却没那么简单,别的不说,就单单C语句解析就是一门大学问。总体来讲,编译过程可以分为以下6步。

  1. 词法分析;
  2. 语法分析;
  3. 语义分析;
  4. 中间代码生成;
  5. 汇编代码生成;
  6. 目标代码生成;

词法分析是编译过程的第一步,主要用来解析C程序语句。词法分析一般会通过词法扫描器从左到右,一个字符一个字符地读入源程序,通过有限状态机解析并识别这些字符流,将源程序分解为一系列不能再分解的记号单元——token。token是字符流解析过程中有意义的最小记号单元,常见的token如下。

  • C语言的各种关键字:int、float、for、while、break等。
  • 用户定义的各种标识符:函数名、变量名、标号等。
  • 字面量:数字、字符串等.
  • 运算符:C语言标准定义的40多个运算符。
  • 分隔符:程序结束符分号、for循环中的逗号等。

假如我们的C源程序中有下面这么一条语句。

sum = a + b / c

经过词法扫描器扫描分析后,就分解成了8个token:“sum”“=”“a”“+”“b”“/”“c”“;”,很多C语言初学者在编写程序时,不小心输入了中文符号、圆角/半角字符导致编译出错,其实就发生在这个阶段。

词法分析结束后,接着进行语法分析。语法分析主要是对前一阶段产生的token序列进行解析,看是否能构建成一个语法上正确的语法短语(程序、语句、表达式等)。语法短语用语法树表示,是一种树型结构,不再是线性序列。如图所示,上面的token序列,经过语法分析,就可以分解为一个语法上正确的语法树。

在这里插入图片描述

语法分析工具在对token序列分析过程中,如果发现不能构建语法上正确的语句或表达式,就会报语法错误:syntax error。如果程序语句后面少了一个语句结束符分号或者在for循环中少了一个分号,报的错误都属于这种语法错误。大家在调试程序时,再遇到syntaxerror的字眼,应该知道问题出在什么地方了吧。

语法分析如果没有出现什么错误,接下来就会进入下一阶段:语义分析。语法分析仅仅对程序做语法检查,对程序、语句的真正意义并不了解,而语义分析主要对语法分析输出的各种表达式、语句进行检查,看看有没有错误。如果你传递给函数的实参与函数声明的形参类型不匹配,或者你使用了一个未声明的变量,或者除数为零了,break在循环语句或switch语句之外出现了,或者在循环语句之外发现了continue语句,一般都会报语义上的错误或警告。

语义分析通过后,接下来就会进入编译的第四个阶段:生成中间代码。在语法分析阶段输出的表达式或程序语句,还是以语法树的形式存储,我们需要将其转换为中间代码。中间代码是编译过程中的一种临时代码,常见的有三地址码、P-代码等。

中间代码和语法树相比,有很多优点:中间代码是一维线性序列结构,类似伪代码,编译器很容易将中间代码翻译成目标代码。如上面的表达式语句。

int main(void)
{int  sum=0;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/814036.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

anaconda创建了虚拟python环境,且安装了pytorch,但是pycharm中import torch运行时报错

报错如下: C:\Users\tashi\.conda\envs\test1\python.exe D:\project\python\transformer\main.py C:\Users\tashi\.conda\envs\test1\lib\site-packages\numpy\__init__.py:127: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL init…

AI预测体彩排3第2弹【2024年4月13日预测--第1套算法开始计算第2次测试】

各位小伙伴,今天实在抱歉,周末回了趟老家,回来比较晚了,数据今天上午跑完后就回老家了,晚上8点多才回来,赶紧把预测结果发出来吧,虽然有点晚了,但是咱们前面说过了,目前的…

将Visio绘图导出PDF文件,使其自适应大小,并去掉导入Latex的边框显示

问题描述 将Visio绘图导成pdf文件,首先在Visio绘图如下: 如果直接导出或者另存为pdf文件,则会发现pdf文件是整个页面大小,而不是图片大小。而且在导入latex等排版工具现实时,会显示边框。 问题解决 1.调整Visio中的页…

vox2vec论文速读

vox2vec: A Framework for Self-supervised Contrastive Learning of Voxel-Level Representations in Medical Images 摘要 本文介绍了 vox2vec——一种体素级表示的自监督学习 (SSL) 对比方法 vox2vec 表示由特征金字塔网络 (FPN&#xf…

Cascader 级联选择器 - 选择器最后一级数据为空

原因:将扁平数据转化为树形数据时,给每个项都添加了 children export const transList2Tree (list, rootPid) > {const result []list.forEach(item > {if (item.pid rootPid) {const children transList2Tree(list, item.id)item.children …

Unity绘制地图

首先在项目/Assets文件夹下创建一个Tiles文件夹 在层级下点击鼠标右键选择2D对象选择瓦片地图创建Tilemap。 选择地图素材 如果素材需要裁剪,在检查器Sprite模式选择多个,点击Sprite Editor,选择切 ,选择类型Grid By Cell Count,…

BoostCompass(建立正排索引和倒排索引模块)

阅读导航 一、模块概述二、编写正排索引和倒排索引模块✅安装 jsoncpp✅Jieba分词库的安装1. 代码基本框架2. 正排索引的建立3. 倒排索引的建立 三、整体代码⭕index.hpp 一、模块概述 这个模块我们定义了一个名为Index的C类,用于构建和维护一个文档索引系统。该系…

【计算机毕业设计】停车场管理系统——后附源码

🎉**欢迎来到琛哥的技术世界!**🎉 📘 博主小档案: 琛哥,一名来自世界500强的资深程序猿,毕业于国内知名985高校。 🔧 技术专长: 琛哥在深度学习任务中展现出卓越的能力&a…

Harmony鸿蒙南向驱动开发-SDIO接口使用

功能简介 SDIO是安全数字输入输出接口(Secure Digital Input and Output)的缩写,是从SD内存卡接口的基础上演化出来的一种外设接口。SDIO接口兼容以前的SD卡,并且可以连接支持SDIO接口的其他设备。 SDIO接口定义了操作SDIO的通用…

21 标准错误

标准输出重定向关闭无数据 下面的代码&#xff1a; #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>int main() {close(1);i…

Xilinx Zynq UltraScale+ MPSoC无人机控制器

官方术语是无人驾驶飞行器&#xff08;UAV&#xff09;&#xff0c;这显然有点拗口&#xff0c;所以我们更喜欢说无人机。在过去的几十年里&#xff0c;无人机技术有了巨大的进步。我们为一个客户开发了一个无人机的飞行和视频控制器。 客户挑战 客户需要一种混合FPGA/CPU硬件&…

是的,本科毕业八年,我考研了

今天&#xff0c;是一篇纯分享文。 是的&#xff0c;本科毕业八年&#xff0c;我考研了。 停更10个月&#xff0c;历时296天&#xff0c;我考研上岸了。 小伙伴们&#xff0c;好久不见。 一 发今年第一篇文章的时候刚处理完后续事宜&#xff0c;就简单说了句&#xff0c;后台…

MoCo v1(CVPR 2020)原理与代码解读

paper&#xff1a;Momentum Contrast for Unsupervised Visual Representation Learning official implementation&#xff1a;https://github.com/facebookresearch/moco 背景 最近的一些研究提出使用对比损失相关的方法进行无监督视觉表征学习并取得了不错的结果。尽管是受…

【DM8】临时表空间

临时表分类 事务级临时表会话级临时表 临时表&#xff0c;可以像普通表一样插入、更新和删除数据临时表的DML操作产生较少的redo日志临时表支持创建索引&#xff0c;以提高查询性能在一个会话或事务结束之后&#xff0c;数据将自动从临时表中删除不同的用户访问相同的临时表&a…

吴恩达深度学习 (week3,4)

文章目录 一、神经网络概述二、神经网络的表示三、神经网络的输出四、多个例子的向量化五、向量化实现的解释六、深度学习激活函数七、激活函数导数八、神经网络的梯度下降法九、深度学习随机初始化十、上述学习总结1、第一题2、第二题3、第三题4、第四题5、第五题6、第六题7、…

关于Transformer的面试题

文章目录 前言1、Transformer模型1. 1 基本要点1.2 提升 2、BN和LN的区别和联系2.1 基本要点2.2 扩展 3、PreNorm和PostNorm的区别[链接](https://www.zhihu.com/question/519668254)4、Multi-head self-attention中为什么要用三个不同的矩阵 前言 Transformer大模型的一些问题…

【GEE实践应用】哨兵1号和2号数据叠加

目录 1.数据叠加代码 2.代码逐句解释 1.数据叠加代码 var geometry table; //table是我们提前导入的矢量数据 // 加载Sentinel-2影像 var sentinel2 ee.ImageCollection("COPERNICUS/S2").filterBounds(geometry) // geometry是你感兴趣区域的几何对象.filte…

Redis:发布和订阅

文章目录 一、介绍二、发布订阅命令 一、介绍 Redis的发布和订阅功能是一种消息通信模式&#xff0c;发送者&#xff08;pub&#xff09;发送消息&#xff0c;订阅者&#xff08;sub&#xff09;接收消息。这种功能使得消息发送者和接收者不需要直接建立连接&#xff0c;而是通…

商标没有去注册有哪些不好的影响!

有些商家咨询普推知产老杨&#xff0c;商标没有去注册有哪些不好的影响&#xff0c;其实对企业来说还有许多实际不利的影响&#xff0c;有时代价比注册一个商标要大很多。 想的商标名称没去注册商标&#xff0c;如果别人抢注拿下商标注册证&#xff0c;那就会涉及侵权&#xf…

工厂方法模式:解锁灵活的对象创建策略

在软件设计中&#xff0c;工厂方法模式是一种非常实用的创建型设计模式&#xff0c;它不仅提升了系统的灵活性&#xff0c;还简化了对象的创建过程。本文将详细探讨工厂方法模式的核心概念、实现方式、应用场景以及与其他设计模式的对比&#xff0c;旨在提供一份全面且实用的指…