C语言系列-编译和链接

 🌈个人主页: 会编辑的果子君

💫个人格言:“成为自己未来的主人~”  

 

目录

翻译环境和运行环境

 编译环境

预处理(预编译)

编译

词法分析

语法分析

语义分析

汇编

链接

运行环境


翻译环境和运行环境

在 ANSIC 的任何一种实现中,存在两个不同的环境

第一种是翻译环境,在这个环境中源代码被转换为可执行的机器指令

第二种是执行环境,它用于实际执行代码

 编译环境

那编译环境是怎么将源代码转换为可执行的机器指令呢?这里我们就得展开讲解一下翻译环境所做的事情。

其实翻译环境是由编译和链接两个大的过程组成的,而编译又可以分解成:预处理(预编译),编译,汇编三个过程。

一个C语言的项目可能有多个.c文件一起构建,那多个.c文件如何生成可执行程序呢?

  • 多个.c文件单独经过编译出编译处理生产对应的目标文件
  • 注:在Windows环境下的目标文件的后缀是.obj,Linux环境下目标文件的后缀是.o
  • 多个目标文件和链接库一起经过链接器处理生成最终的可执行程序
  • 链接库是指运行时库(它是支持程序运行的基本函数集合)或者第三方库 

如果再把编译器展开成三个过程,那就编程了下面的过程

预处理(预编译)

在预处理阶段,源文件和头文件会被处理成为.i为后缀的文件

在gcc环境下想观察一下,对text.c文件预处理后的.i文件,命令如下:

1 gcc -E text.c -o text.i 

预处理阶段主要处理那些源文件中#开始的预编译指令,比如:#include,#define,处理的规则如下:

  • 将所有的#define删除,并展开所有的宏定义
  • 处理所有的文件编译指令,如:#if,#ifdef ,#elif,#else,#endif
  • 处理#include预编译指令,将包含的头文件的内容输入到该预编译指令的位置,这个过程是递归进行的,也就是说被包含的头文件也可能包含其他文件
  • 删除所有的注释
  • 添加行号和文件名标识,方便后续编译器生成调试信息等
  • 或保留所有的#pragma的编译器指令,编译器后续会使用

经过预处理后的.i文件中不再包含宏定义,因为宏已经被展开,并且包含的头文件都被插入到.i文件中,所以当我们无法知道宏定义或者头文件是否正确的时候,可以查看预处理后的.i文件来确认

编译

编译过程就是将预处理后的文件进行一系列的:词法分析,语法分析,语义分析及优化,生成相应的汇编代码文件

编译过程的命令如下:


1 gcc -S text.i -o text.s

对下面代码进行编译的时候,会怎么做呢?假设有下面的代码

1 array[ index ] = ( index + 4)*( 2+6); 

词法分析

将源代码程序被输入扫描器,扫描器的任务就是简单的进行词法分析,把代码中的字符分割成一系列的记号(关键字,标识符,字面量,特殊字符等)

上面的程序进行词法分析后得到了16个记号

语法分析

接下来语法分析器,将对扫描产生的记号进行语法分析,从而产生语法树,这些语法树是以表达式为节点的树。

语义分析

由语义分析器来完成语义分析,即对表达式的语法层面分析,编译器所能做的分析是语义的静态分析。静态语义分析通常包括声明和类型的匹配,类型的转换等,这个阶段会报告错误的语法信息

 

汇编

汇编器是将汇编代码转变成机器可执行的指令,每一个汇编代码几乎都对应一条机器指令,就是根据指令和机器指令的对照表意义一一的进行翻译,也不做指令优化

汇编的命令如下:

1 gcc -c text.s -o text.o 

链接

链接是一个复杂的过程,链接的时候需要把一堆文件链接在一起才生成可执行程序

链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤

链接解决的是一个项目中多文件,多模块之间互相调用的问题

比如,我们已经知道,每个源文件都是单独经过编译器处理生成对应的目标文件

text.c 经过编译器处理生成 text.o

add.c经过编译器处理生成 add.o

我们在text.c的文件中使用了add.c文件中的Add函数和hal变量

我们在text.c文件中每一次使用Add函数和hal的时候必须确切的知道Add和hal的地址,但是由于每个文件都是单独编译的,在编译器编译text.c的时候并不知道Add函数和hal变量的地址,所以暂时把调用Add的指令的目标地址和hal的地址搁置,等待最后链接的时候由链接器根据引用的符号Add在其他模块中查找Add函数的地址,然后将text.c中所有引用到Add的指令重新修正,让他们的目标地址为真正的Add函数的地址,对于全局变量hal也是类似的方法来修正地址,这个地址修正的过程也被叫做:重定位

运行环境

  1. 程序必须载入内存中,在有操作系统的环境中:一般这个由操作系统完成,在独立的环境中,程序的载入必须由手工安排,也可以通过可执行代码置入只读内存来完成
  2. 程序的执行便是开始,接着调用main函数
  3. 开始执行程序代码,这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址,程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程中一直保留他们的值。
  4. 终止程序,正常终止main函数,也有可能是意外终止。 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】图形视图框架 之 坐标

QGraphicsView移动图元/场景以及坐标转换 QGraphicsView图形视图框架使用(一)坐标变换 1.继承 QGraphicsProxyWidget 类 虚函数 mousePressEvent、mouseReleaseEvent 的参数 QGraphicsSceneMouseEvent event->pos() 是item坐标系*下的坐标,不是scene场景坐标系下…

鸿蒙新手入门-环境准备问题解析

Node.js版本与API配套关系 由于SDK的部分工具依赖Node.js运行时,推荐使用配套API版本的Node.js,保证工程的兼容性。 匹配关系见下表: API LevelNode.js支持范围API Level≤914.x(≥14.19.1)、16.xAPI Level>914.…

宠物赛道都卷出了哪些花样?媒介盒子分享

如今的宠物市场,已经从让宠物吃饱喝足的基本生理需求,拓展到五花八门的精神需求,与“马斯洛需求定理”高度一致。商家们看到宠物经济的潜力,不再满足于给人类造节,给毛孩子造节也是重中之重,今天媒介盒子就…

【Java EE初阶十六】网络原理(一)

在网络原理中主要学习TCP/IP四层模型中的重点网络协议 1. 应用层 1.1 应用程序与协议 应用层是和程序员接触最密切的; 应用程序:在应用层这里,很多时候都是程序员自定义应用层协议(步骤:1、根据需求,明确…

Faker遭受DDOS攻击,为什么它一直存在,当遇到ddos攻击怎么办?

二十年前中国红客们就在用的DDOS攻击,直到现在还依然是黑客们最爱的攻击方法,为什么它一直存在? Faker各位小伙伴们自然是相当熟悉了,素有着英雄联盟第一人之称的Faker,其所拥有的荣誉让无数职业选手望其项背&#xf…

如何理解CSS的边框宽度?

CSS 边框宽度学习手记 CSS 边框宽度小概念 在CSS的世界里,border-width这个属性真的很实用,它能帮我指定HTML元素四周边框的宽度。这个宽度嘛,可以用像素px、点pt、厘米cm、相对单位em这些来表示,很方便吧!还有呢&am…

Unity3D Shader 素描风格渲染管线实现详解

前言 在游戏开发中,渲染效果是非常重要的一部分,它可以直接影响游戏的视觉效果和玩家的体验。而素描风格的渲染效果是一种非常独特和有趣的风格,可以为游戏增添一种艺术氛围。在Unity3D中,可以通过编写Shader来实现素描风格的渲染…

三坐标测量机|全自主研发,实现高精度三维尺寸测量

三坐标测量机广泛应用在工业生产中,不仅可以提高生产效率,还能保证产品质量的稳定性。 基本原理和作用介绍 三坐标测量机是一种基于三维坐标系的精密测量仪器,可精确测量物体的尺寸、形状和位置。基本原理是利用传感器测量被测物体在三个方…

STM32学习笔记(七) —— DMA传输(MTM)

DMA,全称是Direct Memory Access(直接内存访问)。可以在存储器和存储器之间或者外设和存储器之间传输数据,而不需要CPU的干预,这样可以节省CPU的资源,提高工作效率。 1.功能框图 STM32F103RCT6有两个DMA控…

外汇天眼:8个平台被打击,有的因诈骗被处罚!

上周,澳大利亚证券和投资委员会(ASIC)取消了总部位于悉尼的Brava Capital的澳大利亚金融服务许可证(AFSL),意大利公司和交易委员会CONSOB则将6个非法投资平台网站列入黑名单。另外,Reiwa-Capita…

蓝桥杯:C++队列、优先队列、链表

C普通队列 算法竞赛中一般用静态数组来模拟队列,或者使用STL queue。使用C的STL queue时,由于不用自己管理队列,因此代码很简洁。队列的部分操作如下。 C优先队列 很多算法需要用到一种特殊的队列:优先队列。它的特点是最优数据…

C++智能指针的知识!

个人主页:PingdiGuo_guo 收录专栏:C干货专栏 大家好呀,我是PingdiGuo_guo,今天我们来学习一下智能指针。 文章目录 1.智能指针的概念 2.智能指针的思想 3.智能指针的作用 3.1 自动内存管理 3.2 共享所有权 3.3 避免悬挂指针…

春节如此“热辣滚烫”,可别把赚钱的机会都让给别人!2024如果创业适合干什么,2024创业新风口

春节期间,在国外抨击我们的旅客不出去旅行,造成了1300亿损失的时候,国内的消费可谓是“热辣又滚烫”,一片勃勃生机的景象。 各个地方纷纷的“亮底牌、放大招”,举办各式各样丰富多彩的文化活动,还进行“农…

自动驾驶中的 DCU、MCU、MPU、SOC 和汽车电子架构

自动驾驶中的 DCU、MCU、MPU 1. 分布式电子电气架构2. 域集中电子电气架构架构2.1 通用硬件定义 3. 车辆集中电子电气架构4. ADAS/AD系统方案演变进程梳理4.1 L0-L2级别的ADAS方案4.2 L2以上级别的ADAS方案 5. MCU和MPU区别5.1 MCU和MPU的区别5.2 CPU与SoC的区别5.3 举个例子 R…

力扣题目训练(15)

2024年2月8日力扣题目训练 2024年2月8日力扣题目训练507. 完美数520. 检测大写字母521. 最长特殊序列 Ⅰ221. 最大正方形237. 删除链表中的节点115. 不同的子序列 2024年2月8日力扣题目训练 2024年2月8日第十五天编程训练,今天主要是进行一些题训练,包括…

基于Robei EDA--实现串口数据包接收

一、定义串口传输协议帧 控制字的数据大小为一字节,定义帧头为(0xFE 0xDF)帧尾为(0xEF) 模块框图 内模块:串口接收,output:8位data 串口命令:对单字节数据接收进行缓存…

去掉图片水印但是不伤原图?看完这些方法就知道了

小伙伴们,你们是不是经常在网上找一些好看的图片作为壁纸呢?有时候会遇到一些带着平台水印的图片,是不是觉得不太美观呢?别着急,其实我们可以使用一些去水印软件来将这些水印去除掉,让图片更加美观。那么&a…

贝塞尔曲线

一条 n n n 次贝塞尔曲线可以表示为 C ( u ) ∑ i 0 n B i , n ( u ) P i , 0 ≤ u ≤ 1 (1) \pmb C(u)\sum_{i0}^nB_{i,n}(u)\pmb{P_i},\quad 0\leq u\leq1\tag{1} C(u)i0∑n​Bi,n​(u)Pi​,0≤u≤1(1) 其中,基函数(也称为混合函数) {…

电商行业的机遇在哪?致淘宝平台API数据接口

在电商行业蓬勃发展的今天,我们不得不提及淘宝这个伟大的平台。它不仅为亿万用户提供了便捷的购物体验,更为无数的商家创造了一个财富的聚集地。而如今,随着技术的不断进步,淘宝开放了其强大的API接口,为广大开发者带来…

【开工大吉】推荐4款开源美观的WPF UI组件库

前言 经常有小伙伴在技术群里提问:WPF有什么好用的UI组件库?,今天大姚给大家推荐4款开源、美观的WPF UI组件库。 WPF介绍 WPF 是一个强大的桌面应用程序框架,用于构建具有丰富用户界面的 Windows 应用。它提供了灵活的布局、数据绑定、样式…