【C语言】编译与链接:深入理解程序构建过程

请添加图片描述
🔥引言

本篇将深入理解程序构建过程,以便于我们在编写程序的过程同时,理解底层是如何从程序的创建到生成可执行程序的。

请添加图片描述
Alt

🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
请添加图片描述

文章目录

  • 一、翻译环境和运行环境
  • 二、翻译环境
    • 2.1 预处理(预编译)
    • 2.2 编译
      • 2.2.1 词法分析
      • 2.2.2 语法分析
      • 2.2.4 语义分析
    • 2.3 汇编
    • 2.4 链接
    • 三、运行环境


一、翻译环境和运行环境

ANSI C是由美国国家标准协会(ANSI)及国际标准化组织(ISO)推出的关于->C语言的标准。在ANSI C的任何一种是实现中,存在两个不同的环境。

  • 翻译环境:环境中源代码被转换为可执行的机器指令(二进制指令)
  • 执行环境:用于实际执行代码

在这里插入图片描述


二、翻译环境

翻译环境是由编译和链接两个大过程组成的,将源代码转换为可执行的机器指令,编译又可以分解成:预处理(预编译)、编译、汇编三个过程。

在这里插入图片描述

说明】:

  • 多个.c文件单独经历编译处理生产对应的目标文件
  • 多个目标文件和链接库一起经过链接器处理生成可执行程序
  • 链接库是指运行时库(支持程序运行的基本库函数集合)或者第三方库

(目标文件:windows环境下后缀为.obj,Linux环境下后缀为.o)


2.1 预处理(预编译)

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

预处理阶段主要处理源文件中如下规则:

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

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


2.2 编译

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

编译过程命令:

gcc -S test.i -o test.s

比如:对下列表达式进行处理:

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

2.2.1 词法分析

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

在这里插入图片描述

2.2.2 语法分析

将对扫描产生的记号进行语法分析,从而产生语法树(以表达式为节点的树)。在这里插入图片描述

2.2.4 语义分析

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

2.3 汇编

由汇编器将汇编代码转为机器指令(二进制指令),每一句汇编语句几乎都对应一条机器指令。按照汇编指令和机器指令的对照表进行一一的进行翻译,不做指令优化

汇编的命令如下:

gcc -c test.s -0  test.o

2.4 链接

一堆文件链接在一起生成可执行程序,为解决一个项目中多文件、多模块之间互相调用的问题。

主要过程:地址和空间分配,符号决议和重定位等步骤

<test.c>
    extern int g_val;
extern Add(int x,int y);
int main()
{
    int a=10;
    int b=20;
    Add(a,b);
    printf("%d",g_val);
    return 0;
}
<Add.c>
    int g_val=10;
int Add(int x,int y)
{
    return x+y;
}

说明】:每个源文件多是单独经过编译器处理生成对应的目标文件

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

其中在test.c文件中使用extern声明其他文件的外部符号。在test.c文件中使用Add函数和g_val变量时,必须需要知道Add函数和g_val变量的地址,但是由于每个文件是单独编译的,在编译器test.c时并不知道Add函数和g_val变量的地址,所以暂时把调用Add的指令的目标地址和g_val的地址搁置 。等到最后的链接操作由链接器根据引用符号Add在其他模块中查找Add函数的地址,然后将test.c中所用引用到Add的指令重新修正,让调用Add的指令的目标地址成为真正Add函数的地址,对于全局变量g_val也是类似的方法修改地址。这个地址修改的过程也被称为:重定位。


三、运行环境

  1. 程序必须载入内存中,在操作系统的环境下:一般这个由操作系统完成在独立的环境下:程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成的
  2. 程序的执行开始–>调用main函数
  3. 开始执行程序代码。程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址,程序同时也可以使用静态内存,存储在静态区的变量,生命周期跟程序的整个执行过程一样长。
  4. 终止程序。正常终止main函数,也可能异常终止。

请添加图片描述
以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二C语言笔记,希望对你在学习C语言中有所帮助!接下来,我们将进入初阶数据结构的学习中

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

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

相关文章

django使用fetch上传文件

在上一篇文章中&#xff0c;我包装了fetch方法&#xff0c;使其携带cookie。但是之前fetch传递的是json数据&#xff0c;现在有了一个上传文件的需求&#xff0c;因此需要进行修改&#xff1a; const sendRequest (url, method, data) > {const csrftoken Cookies.get(cs…

【Effective Python教程】(90个有效方法)笔记——第1章:培养pythonic思维——7:尽量用enumerate取代range

文章目录 第1章&#xff1a;培养pythonic思维第7条 尽量用enumerate取代range&#xff08;移位操作、位掩码&#xff09;要点enumerate函数可以用简洁的代码选代iterator&#xff0c;而且可以指出当前这轮循环的序号。不要先通过range指定下标的取值范围&#xff0c;然后用下标…

Linux eBPF:网络、系统监控和安全领域的创新

扩展 Berkeley Packet Filter&#xff08;eBPF&#xff09;是Linux内核中的一项强大技术&#xff0c;最初用于网络数据包过滤。随着时间的推移&#xff0c;eBPF的功能和应用场景不断扩展&#xff0c;如今已成为网络、系统监控和安全等领域的重要工具。eBPF可以在Linux内核中安全…

Halcon 双相机标定与拼图(一)

二、算子解释 get_calib_data camera-pose 获得基于第一个相机的第二个相机的Pose get_calib_data (CalibDataID, camera, 1, pose, RelPose2) *relative 相对 * To get the absolute pose of the second camera, its relative pose needs * to be inverted and combined…

2024 cicsn magicvm

文章目录 参考检查逆向vm::runvm::vmvm_alu::set_inputvm_mem::set_inputvm_id::runvm_alu::runvm_mem::run 漏洞思路参考的exp 参考 https://forum.butian.net/share/3048 https://akaieurus.github.io/2024/05/20/2024%E5%9B%BD%E8%B5%9B%E5%88%9D%E8%B5%9Bpwn-wp/#SuperHea…

【Nacos_bugs】java.lang.IllegalStateException: Failed to load ApplicationContext

报错原因 找不到配置文件。 Bug 排查 如果使用 Nacos 管理配置文件&#xff0c;需要检查本地 bootstrap.yml 配置是否出现问题&#xff1a; 检查点&#xff1a; 检查 Nacos 服务的地址有没有配置错误&#xff0c;如上图 ①&#xff0c;格式严格为 IP:端口号" 检查 D…

Mongodb的数据库简介、docker部署、操作语句以及java应用

Mongodb的数据库简介、docker部署、操作语句以及java应用 本文主要介绍了mongodb的基础概念和特点&#xff0c;以及基于docker的mongodb部署方法&#xff0c;最后介绍了mongodb的常用数据库操作语句&#xff08;增删改查等&#xff09;以及java下的常用语句。 一、基础概念 …

WebPack插件实现:打包之后自动混淆加密JS文件

在WebPack中调用JShaman&#xff0c;实现对编译打包生成的JS文件混淆加密 一、插件实现 1、插件JShamanObfuscatorPlugin.js&#xff0c;代码&#xff1a; class JShamanObfuscatorPlugin { apply(compiler) { compiler.hooks.emit.tapAsync(JShamanObfuscatorPlugin, (comp…

【Python网络爬虫】详解python爬虫中正则表达式、BeautifulSoup和lxml数据解析

&#x1f517; 运行环境&#xff1a;PYTHON &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

SpringMVC日期格式处理 分页条件查询

实现日期格式处理 实现分页条件查询&#xff1a; 分页条件查询 和 查询所有 是两个不同的方法&#xff0c;使用同一个mapper的查询功能&#xff0c;但是两个不同的业务方法 ​​​​​​​

2024年5月2日 Go生态洞察:Go 1.22中的安全随机性

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a;…

切勿大意!痉挛性斜颈治疗中的三个重要“禁忌”,后果堪忧!

今天&#xff0c;要给大家讲一个非常重要的话题——痉挛性斜颈的治疗。痉挛性斜颈是一种常见的神经肌肉疾病&#xff0c;患者在日常生活中可能会遇到许多困扰和不便。因此&#xff0c;及早治疗对患者来说至关重要。 然而&#xff0c;在治疗痉挛性斜颈的过程中&#xff0c;千万切…

计算机网络学习实践:模拟RIP动态路由

计算机网络学习实践&#xff1a;模拟RIP动态路由 模拟动态路由RIP协议 1.实验准备 实验环境&#xff1a;华为模拟器ENSP 实验设备&#xff1a; 3个路由器&#xff0c;3个二层交换机&#xff08;不是三层的&#xff09;&#xff0c;3个PC机 5个网段 192.168.1.0 255.255.…

计算机网络学习实践:DHCP跨网段动态分配IP

计算机网络学习实践&#xff1a;DHCP跨网段动态分配IP 1.实验准备 实验环境&#xff1a;思科的模拟器 实验设备&#xff1a; 1个服务器&#xff0c;2个二层交换机&#xff08;不是三层的&#xff09;&#xff0c;4个PC机&#xff0c;1个路由器 三个网段 192.168.1.0 255.…

【操作系统】详谈操作系统的发展历程

文章主题 导读一、手工操作阶段1.1 计算机的诞生1.2 计算机的使用 二、批处理阶段2.1 单道批处理系统2.2 多道批处理系统 三、分时操作系统3.1 分时技术3.2 分时操作系统3.1 分时系统的主要特征 四、实时操作系统五、网络操作系统和分布式计算机系统六、个人计算机操作系统结语…

【cdo专辑】2.1 文件信息(下)

目录 0.先cd进数据路径&#xff08;进行操作前一定要进入数据文件夹奥&#xff09; 1.输出文件格式&#xff08; cdo showformat nc文件&#xff09; 2.输出变量名&#xff08; cdo showname nc文件&#xff09; 3.输出变量标准名称&#xff08; cdo showstdname nc文件&am…

从“百模”到“千体”:大模型智能体的竞争格局、商业模式和技术挑战

原本平静的5月&#xff0c;从14日凌晨OpenAI发布GPT-4o开始热闹起来。 一天之后&#xff0c;谷歌在一年一度的开发者大会上发布智能助理项目Astra和轻量化多模态模型Gemini 1.5 Flash。 同一天&#xff0c;字节升级了AI助手“豆包”和应用开发平台“扣子”&#xff0c;并发布…

Postgre数据库初探

一、PostgreSQL介绍 PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES&#xff0c; 版本 4.2为基础的对象关系型数据库管理系统&#xff08;ORDBMS&#xff09;。POSTGRES 领先的许多概念在很久以后才出现在一些商业数据库系统中。 PostgreSQL是最初的伯克利代码的开…

linux内核零拷贝技术详解

1.前言 Linux系统中一切皆文件&#xff0c;仔细想一下Linux系统的很多活动无外乎读操作和写操作&#xff0c;零拷贝就是为了提高读写性能而出现的。 2. 数据拷贝基础过程 在Linux系统内部缓存和内存容量都是有限的&#xff0c;更多的数据都是存储在磁盘中。对于Web服务器来说…

linux系统上shell脚本编写问题总结

需求背景&#xff1a;项目技术栈&#xff1a;Vue2Nuxt2TypeScript&#xff0c;是一个服务端渲染的项目&#xff0c;每次打测试包时需要在虚拟机上通过命令行打包项目&#xff0c;然后将打包生成的文件压缩为一个压缩包.tar.gz&#xff0c;然后将这个压缩包下载到本地&#xff0…