编译和链接

预处理、编译、汇编和链接 说明 C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码)。流程包括:预处理、编译、汇编和链接。hello.c文件为一个自己写好的包含main函数的c文件。 预处理 第一个阶段是预处理阶段,在正式的编译阶段之前进行。预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容。如#include指令就是一个预处理指令,它把头文件的内容添加到.cpp文件中... 阅读详情

✨✨ 欢迎大家来到莉莉的博文✨✨

 🎈🎈养成好习惯,先赞后看哦~🎈🎈

 翻译环境和编译环境

  • 翻译环境,在这个环境中 源代码  被转换为 可执行的机器指令(⼆进制指令)。
  • 执行环境,它用于实际执行代码。

一、 翻译环境

        翻译环境是由 编译和链接 两个大的过程组成的,而编译又可以分解成:预处理(有些书也叫预编译)、编译、汇编三个过程。         一个C语言的项目中可能有多个 .c 文件一起构建,那多个 .c 文件如何生成可执行程序呢

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

        如果再把编译器展开成3个过程,那就变成了下面的过程:(以gcc编译器为例)

1.1 预处理(预编译)

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

在 gcc 环境下想观察⼀下,对 test.c 文件预处理后的.i文件,命令如下: 1 gcc -E test.c -o test.i

预处理阶段主要处理那些源文件中#开始的预编译指令。

比如:#include,#define,处理的规则如下:

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

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

1.2 编译——>  .i文件生成汇编代码文件

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

 1.2.1 词法分析

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

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

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

1.2.2 语法分析

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

1.2.3 语义分析

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

1.3 汇编

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

1.4 链接

        链接是一个复杂的过程,链接的时候需要把一堆文件链接在一起才生成可执行程序。 链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤。

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

        这个过程可以发现被调用的函数是否未定义

比如:

//text.c
#include <stdio.h>
//声明外部函数
extern int Add(int x, int y);
//声明外部的全局变量
extern int g_val;
int main()
{
     int a = 10;
     int b = 20;
     int sum = Add(a, b);
     printf("%d\n", sum);
     return 0;
}
//add.c
int g_val = 2022;
int Add(int x, int y)
{
     return x+y;
}

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

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

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

我们在 test.c 的文件中使用了 add.c 文件中的 Add 函数和 g_val 变量。

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

二、运行环境

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

 

C/C++的编译和链接过程 cl.exe和link.exe分别是visual studio 中的编译器和链接器 配置属性中的【c/c++】(设置编译的一些选项) 和 【链接器】选项页中,最后的那个命令行汇总了所有生效的设置,就是最终执行的命令行 配置属性中的VC++ 目录用于设置各个路径,相当于设置环境变量PATH(搜可执行文件的路径): INCLUDE(搜include中文件的路径) LIBPATH(搜使用usin... 阅读详情

相关推荐

深入解析EDID中Display Descriptor Block的配置技巧与实战应用

本文深入解析EDID中Display Descriptor Block的配置技巧与实战应用。通过剖析像素时钟、有效像素、消隐区与同步脉冲等核心参数,并结合1280x720@60Hz的实战配置案例,指导开发者如何正确为定制硬件或非标准显示器编写“身份证”,避免黑屏、分辨率异常等问题,确保显示设备完美点亮。

1a2s3d4f5g的博客 878

详解C语言的编译与链接

你知道从源代码到可执行文件经历了哪些过程吗?

m0_50655389的博客 8298

XC7Z010-1CLG400C开发板ADC引脚配置全攻略(附完整引脚列表)

本文详细解析了XC7Z010-1CLG400C开发板的ADC引脚配置方法,涵盖XADC模块基础、CLG400封装的引脚布局、硬件设计规范及Vivado工程配置实战。特别提供了完整的引脚列表和性能优化技巧,帮助开发者高效实现模拟信号采集,适用于Zynq-7000系列开发。

weixin_29188043的博客 465

【C语言】程序编译链接详解

通过加选项-s来查看test.o,add.o形成的符号表。

weixin_62529445的博客 2990

NCCL 核心集体通信操作深度解析:从原理到优化实践

操作逻辑:若 N 个 GPU 各持有一段数据(大小为 S),通信后每个 GPU 会持有所有 N 段数据(总大小为 N×S)。典型场景:多卡推理结果聚合、模型并行中间结果同步。操作逻辑:N 个 GPU 各持有数据,通过归约(求和、取平均等)运算后,所有 GPU 获得相同结果。典型场景:数据并行训练的梯度聚合(如 SGD 优化器)。操作逻辑:N 个 GPU 各持有 N 份数据分片,通信后每个 GPU 获得所有 GPU 的对应分片。典型场景。

jundao1997的专栏 678

零基础学simulink仿真建模--基于Simulink进行近端策略优化(PPO)路径规划的仿真建模

特点高效性与稳定性:通过引入剪裁机制,在更新策略时限制步长,从而提高了训练过程的稳定性和效率。适用于多种动作空间:可以处理连续和离散的动作空间问题。无需模型:不需要预先知道环境的确切模型,适合复杂或未知环境。挑战收敛速度与稳定性:确保算法能够在合理的时间内找到近似最优解,并保持训练过程的稳定性。探索与利用平衡:在探索新路径和利用已知信息之间取得平衡。计算资源:对于大规模状态空间和动作空间,计算资源需求较高。首先明确要模拟的任务内容。目标(例如到达指定地点、避开障碍物等)。

amy_mhd的博客 249

C语言 编译和链接

_FILE__ // 进行编译的源文件__LINE__ // 文件当前的行号__DATE__ // 文件被编译的日期__TIME__ // 文件被编译的时间__STDC__ // 如果编译器遵循 ANSI C,其值为 1,否则未定义100// 预处理后变成:int n = 100;// 预处理后变成:char arr[] = "hello world";return 0;// 输出结果:// 100int a = 10;int b = 20;

lfm1010123的博客 3527

深度学习在地质勘探中的应用:使用Python构建卷积神经网络进行地震数据分析

在本文中,我们介绍了如何利用深度学习技术,特别是卷积神经网络(CNN),来处理和分析地震数据。我们使用了Python编程语言和TensorFlow框架构建了一个CNN模型,并使用地震数据进行了训练和评估。在本文中,我们将探讨如何利用深度学习技术,特别是卷积神经网络(CNN),来处理和分析地震数据。首先,我们需要获取地震数据集。通过本文的介绍,希望您能对深度学习在地质勘探领域的应用有更深入的了解,并能够应用这些技术来解决实际问题。在准备好地震数据和构建CNN模型后,我们需要将数据分为训练集和测试集。

斌擎科技 1471

【c语言】编译链接--详解

3.处理#include 预编译指令,将包含的头⽂件的内容插⼊到该预编译指令的位置。这个过程是递归进⾏的,也就是说被包含的头⽂件也可能包含其他⽂件。汇编器是将汇编代码转转变成机器可执⾏的指令,每⼀个汇编语句⼏乎都对应⼀条机器指令。,将对扫描产⽣的记号进⾏语法分析,从⽽产⽣语法树。将代码分割成一系列的记号,例如**(关键字、标识符、字⾯量、特殊字符等)**据汇编指令和机器指令的对照表⼀⼀的进⾏翻译,也不做指令优化。对下⾯代码进⾏编译的时候,会怎么做呢?在ANSI C的任何⼀种实现中,存在两个不同的环境。

daydayup 769

手把手教你学simulink(8.2)--simulink的实战案例:信号分析

通过以上步骤,你已经成功使用 Simulink 对信号进行了频谱分析和时域分析,提取了信号的有用信息。这个案例展示了如何创建 Simulink 模型、添加和连接模块、设置仿真参数、运行仿真以及分析结果。希望这个案例能帮助你更好地理解和使用 Simulink 进行信号分析。

MHD0815的博客 1123

手机相机Tuning专项调优(一):基础流程与图像主观评价标准建立实战解析

本篇为手机相机系统“Tuning专项调优”系列的开篇,深入剖析了当前手机相机Tuning的基本流程与图像主观评价标准的构建方法。结合实际工程经验与最新业界案例,详细介绍ISP调优和3A控制中涉及的主观评价标准,如锐度、色彩饱和度、噪声感知等,并提出一套可工程化落地的标准制定与评测实践体系,帮助工程师有效提升图像品质。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1933

编译和链接的过程

程序要运行起来,必须要经过四个步骤:预处理、编译、汇编和链接。接下来通过几个简单的例子来详细讲解一下这些过程。 对于上边用到的几个选项需要说明一下。 使用 gcc 命令不跟任何的选项的话,会默认执行预处理、编译、汇编、链接这整个过程,如果程序没有错,就会得到一个可执行文件,默认为a.out -E选项:提示编译器执行完预处理就停下来,后边的编译、汇编、链接就先不执行了。 -S选项:提示编...

半暖的博客 4万+

SAP SD销售订单的ATP检查简介

如果可用性检查组设置为01(汇总需求),系统将更新销售订单需求到汇总表VBBS,该表中未记录销售订单号码,因此在MD04中不会显示销售订单号码,而是按天汇总显示销售需求。如果物料的可用性检查组设置为02(单个需求),系统将更新销售订单需求到表VBBE,该表中记录了销售订单号码,因此在MD04显示销售订单的号码以及需求,前面的文章中我们解释了PP模块中的ATP检查,也解释了MM模块中的ATP的检查,本文将说明一下SD模块中的ATP检查。可用性检查用的最多的就是02,有兴趣的同学可以测试一下可用性检查01。

我小时候很黑的博客 4291

c语言中编译和链接

在 ANSI C 的任何⼀种实现中,存在两个不同的环境。第1种是翻译环境,在这个环境中源代码被转换为可执⾏的机器指令(⼆进制指令)。第2种是执⾏环境,它⽤于实际执⾏代码。

2403_88562595的博客 1835

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【C语言】编译和链接

在ANSI C的任何一种实现中,存在着两个不同的环境:1、翻译环境:在翻译环境中,其会通过编译和链接两个大的步骤,其中编译又分为了预处理(这 个我们后面还会详细讲解),编译和汇编,然后将源代码转换为可执行的机器指令(二进制指 令),然后生成可执行文件。2、运行环境:就是执行环境,在运行环境中会执行可执行程序,然后输出结果。下面我们将在翻译环境和运行环境下具体是干啥的。

2302_81083101的博客 1491

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: fread和fwirte函数
下一篇: 【oj题】环形链表
大力初奇迹
博客等级 码龄3年 1294粉丝 54原创
评论 22
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值