编译和链接(超详细)

✅博客主页:爆打维c-CSDN博客​​​​​​ 🐾

🔹分享c语言知识及代码


一、编译和链接实例

假设我们有一个名为main.c的C语言源文件,它包含了一个简单的Hello World程序。我们可以使用gcc编译器对该源文件进行编译,生成一个可执行文件。具体步骤如下:

  1. 预处理:首先,gcc编译器会对main.c文件进行预处理,处理其中的宏定义、条件编译等指令,生成一个预处理后的文件(通常为.i文件)。
  2. 编译:然后,gcc编译器会对预处理后的文件进行编译,将其转换为汇编代码文件(通常为.s文件)。这个过程包括了词法分析、语法分析、语义分析和优化等步骤。
  3. 汇编:接着,汇编器会将汇编代码文件转换为机器语言的目标文件(通常为.o文件)。
  4. 链接:最后,链接器会将目标文件和必要的库文件进行链接,生成一个可执行的二进制文件(如a.out)。

二、预处理、编译、汇编、链接详解

1. 预处理(预编译)

在预处理阶段,源⽂件和头⽂件会被处理成为.i为后缀的⽂件。
gcc 环境下想观察⼀下,对 test.c ⽂件预处理后的.i⽂件,命令如下:
  gcc -E test.c -o test.i
预处理阶段主要处理那些源⽂件中#开始的预编译指令。⽐如:#include,#define,处理的规则如下:
将所有的 #define 删除,并展开所有的宏定义。
处理所有的条件编译指令,如: #if #ifdef #elif #else #endif
处理#include 预编译指令,将包含的头⽂件的内容插⼊到该预编译指令的位置。这个过程是递归进
⾏的,也就是说被包含的头⽂件也可能包含其他⽂件。
删除所有的注释
添加⾏号和⽂件名标识,⽅便后续编译器⽣成调试信息等。
或保留所有的#pragma的编译器指令,编译器后续会使⽤。
经过预处理后的.i⽂件中不再包含宏定义,因为宏已经被展开。并且包含的头⽂件都被插⼊到.i⽂件
中。所以当我们⽆法知道宏定义或者头⽂件是否包含正确的时候,可以查看预处理后的.i⽂件来确认。

2. 编译

编译是将预处理后的源代码转换为汇编代码的过程。编译器会检查源代码的语法和语义错误,并生成一个或多个汇编文件。
编译过程的命令如下:
1 gcc -S test.i -o test.s

在编译阶段,编译器会进行以下操作:

  • 词法分析:将源代码分解为一系列的记号(tokens)或词汇单元(lexical units),如变量名、关键字、操作符、标点符号等。
  • 语法分析:根据语言的语法规则,将记号组合成语法结构(如表达式、语句、程序块等)。
  • 语义分析:检查源代码的语义,确保它们有意义。例如,检查变量是否在使用前已定义,函数调用的参数是否与函数定义匹配等。
  • 中间代码生成:将源代码转换为一种中间表示形式(如三地址码),以便后续的优化和汇编。
  • 优化:对中间代码进行优化,以提高程序的执行效率。
  • 目标代码生成:将优化后的中间代码转换为特定机器或目标平台的汇编代码。

3. 汇编

汇编器是将汇编代码转转变成机器可执⾏的指令,每⼀个汇编语句⼏乎都对应⼀条机器指令。就是根据汇编指令和机器指令的对照表⼀⼀的进⾏翻译,也不做指令优化。
汇编的命令如下:
gcc -c test.s -o test.o

4.链接

链接是⼀个复杂的过程,链接的时候需要把⼀堆⽂件链接在⼀起才⽣成可执⾏程序。
链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤。
比如写了一个项目,有多个文件
每个文件都是独立的, 每个源⽂件都是单独经过编译器处理⽣成对应的⽬标⽂件。
我们在 test.c 文件中每一次使用snake.c 中的函数时的必须确切的知道snake.c 中的函数的地址,但是由于每个文件是单独编译的,在编译器编译 test.c的时候并不知道snake.c 中的函数的地址,(假设使用Add函数)所以暂时把调用Add函数指令的目标地址搁置。等待最后链接的时候由链接器根据引用的符号,在其他模块中查找Add函数的地址,然后将 test.c 中所有引用到Add函数的指令重新修正,让他们的目标地址为真正的 Add 函数的地址,对于全局变量也是类似的方法来修正地址。这个地址修正的过程也被叫做: 重定位。

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

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

相关文章

出海战略与网络技术:SOCKS5代理、代理IP与跨界电商与游戏行业的全球扩展

在全球市场日益融合的今天,中国的电商与游戏企业越来越多地采用“出海”战略,寻求在国际市场中拓展业务。在这一过程中,技术手段如SOCKS5代理和代理IP在网络安全和数据流通方面发挥着关键作用。本文旨在探讨这些技术如何助力跨界电商和游戏行…

AI大模型探索之路-训练篇18:大语言模型预训练-微调技术之Prompt Tuning

系列篇章💥 AI大模型探索之路-训练篇1:大语言模型微调基础认知 AI大模型探索之路-训练篇2:大语言模型预训练基础认知 AI大模型探索之路-训练篇3:大语言模型全景解读 AI大模型探索之路-训练篇4:大语言模型训练数据集概…

亚马逊是如何铺设多个IP账号实现销量大卖的?

一、针对亚马逊平台机制,如何转变思路? 众所周知,一个亚马逊卖家只能够开一个账号,一家店铺,这是亚马逊平台明确规定的。平台如此严格限定,为的就是保护卖家,防止卖家重复铺货销售相同的产品&a…

【读论文】Gaussian Grouping: Segment and Edit Anything in 3D Scenes

Gaussian Grouping: Segment and Edit Anything in 3D Scenes 文章目录 Gaussian Grouping: Segment and Edit Anything in 3D Scenes1. What2. Why3. How3.1 Anything Mask Input and Consistency3.2 3D Gaussian Rendering and Grouping3.3 Downstream: Local Gaussian Editi…

10000 字详细讲解 Spring 中常用注解及其使用

如下图京东购物页面,当我们选择点击访问某一类商品时,就会向后端发起 HTTP 请求,当后端收到请求时,就会找到对应的代码逻辑对请求进行处理,那么,后端是如何来查找处理请求相对应的代码呢?答案就…

七、VUE过滤器

一、初识VUE 二、再识VUE-MVVM 三、VUE数据代理 四、VUE事件处理 五、VUE计算属性 六、Vue监视属性 七、VUE过滤器 七、VUE内置指令 九、VUE组件 过滤器: 对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。 语法&#xff…

计算机考研|25人太难了,408会炸,还是自命题会炸?

自命题已经不是炸不炸的问题了,是有没有学上的问题。 我记得去年九月一些学校宣布改考408的时候,整个群里都炸了,同学一片哀嚎。要知道九月的时候要重新准备408肯定是不可能了,一来408复习的基础阶段已经过去了,二来英…

人工智能哪些大学比较好

人工智能领域的大学有很多,以下是一些国际上被广泛认可的一流大学: 1. **斯坦福大学(Stanford University)** - 位于美国加州的斯坦福大学拥有顶尖的人工智能研究中心,并在机器学习、自然语言处理等领域处于领先地位。…

phpstudy(MySQL启动又立马停止)问题的解决办法

方法一:查看本地安装的MySQL有没有启动 1.鼠标右击开始按钮选择计算机管理 2.点击服务和应用程序 3.找到服务双击 4.找到MySQL服务 5.双击查看是否启动,如启动则停止他,然后确定,重新打开phpstudy,启动Mysql. 方法二&#xff…

Scala特殊符号含义

1. ::: (三个冒号)只用于连接两个List类型的集合 val a List(1,2) val b List(3,4) val c a ::: b2. :: (两个冒号)表示普通元素与List的连接操作 val a 1 val b List(3,4) val c 1 :: b::是右侧对象的方法,即它是对象b的…

利用webpack拆分css

利用webpack拆分css {ignore} 要拆分css,就必须把css当成像js那样的模块;要把css当成模块,就必须有一个构建工具(webpack),它具备合并代码的能力 而webpack本身只能读取css文件的内容、将其当作JS代码进行…

【Langchain实践】Few-shot examples for chat models 学习记录

构建向量存储 知识库examples是一个列表,列表元素是字典。与输入相关的文本放在from_text函数的第一个参数。embedding是嵌入模型,这部分如何使用本地模型,参考上一篇博客。metadatas是原始数据,也就是知识库。 to_vectorize […

C#:求解出n以内所有能被5整除的正整数的乘积

任务描述 本关任务:求解出n以内(包含n)所有能被5整除的正整数数的乘积s。 输入 从键盘输入一个正整数n,输入的n不超过100。 输出 对于每个样例n,输出n以内(包含n)所有能被5整除的正整数的乘积。 样例输入 19 ####样…

[鸟哥私房菜]4.首次登录与在线求助

第4章 首次登录与在线求助 4.1.3 X Window 与命令行模式的切换 通常我们称命令行界面为终端界面、Terminal 或 Console。Linux 默认的情况下会提供六个终端(Terminal)来让用户登录, 切换的方式为使用:[Ctrl] [Alt] [F1]~[F6] …

折腾记:C++用开源库Snap7通过S7协议连接西门子PLC

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 不是教程,是避坑指…

2022年知识付费小程序案例分享资料,海量收录.完整版,线上销售沟通的技巧和方法,怎么进行沟通?

现在是互联网时代,很多购物平台和知识付费平台在网上全面开花,因此也诞生了销售员的工作也从线下转到了线上。线上销售毕竟不同于线下销售,想要将产品卖出去,沟通的技巧和方式也很重要。 一、 线上销售沟通前的准备 1、 心理上的准…

‘ChatGLMTokenizer‘ object has no attribute ‘sp_tokenizer‘

问题 ‘ChatGLMTokenizer’ object has no attribute ‘sp_tokenizer’ 解决方案 将self.sp_tokenizer SPTokenizer(vocab_file, num_image_tokensnum_image_tokens)移动到super().init()前面 self.sp_tokenizer SPTokenizer(vocab_file, num_image_tokensnum_image_token…

TypeScript学习日志-第十七天(泛型约束)

泛型约束 当我们使用泛型时非常方便,但是在使用的过程中也会遇到很多问题,如图: 这时候就会提示错误,因为返回的是相加的值,但是不是所有的类型都能相加的,例如来个undefined类型的 就不能进行相加了&…

回顾5款我非常喜欢的软件,希望大家也能喜欢

​ 我喜欢分享好软件,这就像与老友聊天一样让我感到快乐。在这个过程中,我可以回顾这些实用的小工具,也希望它们可以帮助到更多人。 1.备份工具——Cobian Backup ​ Cobian Backup是一款功能强大的备份软件,支持自动定时备份、增量备份、差异备份等多种备份方式。…

知识付费系统 设计,课程顾问怎么跟家长微信互动?这样去维护客户

当今天下,营销方式层出不穷,可是有些机构比较保守,始终坚持自己独有的一套模式,并且屡试不爽,今天,小编就带着大家一起来聊一聊课程顾问怎么跟家长微信互动。 维系客户客户有三个方面: 1:微信私…