编译与链接(想了解编译与链接,那么看这一篇就足够了!)

news2024/11/25 10:15:52

        前言:在我们练习编程的时候,我们只需要将代码写入、运行,就可以得到计算之后的结果了,但是你有没有想过,为什么就可以得到计算之后的结果呢,它的底层又到底是什么呢?


✨✨✨这里是秋刀鱼不做梦的BLOG

✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客

那么废话不多说,我们直接开始讲解,先来看一下讲解内容:

目录

1.翻译环境

        (1)编译

        [ 1 ]预处理阶段

        [ 2 ]编译阶段

        [ 3 ]汇编阶段

        (2)链接

2.运行环境


1.翻译环境

        由于操作系统只能执行机器指令(二进制指令),所以翻译环境阶段要做的就是将写入的代码转化为二进制指令,而翻译环境是由编译和链接两个大的过程组成,编译又可以分解成:预处理、编译、汇编三个过程。

大致如图:

接下来让我们一个一个来讲解:

        

        (1)编译

编译流程大致分为了四个步骤:

        [ 1 ]预处理阶段

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

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

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

        [ 2 ]编译阶段

编译过程就是将预处理后的文件进行一系列从而生成相应的汇编代码文件,编译过程可分为6步:扫描(词法分析)、语法分析、语义分析、源代码优化、代码生成、目标代码优化

1. 词法分析:扫描器将源代的字符序列分割成一系列的记号。

2. 语法分析:语法分析器将记号产生语法树。

3. 语义分析:静态语义(在编译器可以确定的语义),动态语义(只能在运行期才能确定的语义)。

4. 源代码优化:源代码优化器,将整个语法书转化为中间代码(中间代码是与目标机器和运行环境无关的),中间代码使得编译器被分为前端和后端,编译器前端负责产生机器无关的中间代码,编译器后端将中间代码转化为目标机器代码。

5. 目标代码生成:代码生成器。

6. 目标代码优化:目标代码优化器。

        [ 3 ]汇编阶段

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

所以编译阶段大致可以使用以下方式描述:

        (2)链接

链接的简介:

链接(linking)是将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并执行。链接可以执行于编译时(compile time),也就是在源代码被翻译成机器代码时;也可以执行于加载时(load time),也就是在程序被加载器(loader)加载到内存并执行时;甚至执行于运行时(run time),也就是由应用程序来执行。链接是由叫链接器(linker)的程序自动执行的

        链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤,其解决的是一个项目中多文件、多模块之间互相调用的问题。

        那么为什么要有链接过程呢:因为编译只是将我们写的代码变成了二进制形式,它还要需要和系统组件(比如标准库、动态链接库等)结合起来,这些组件都是程序运行所必须的。
 

所以链接简而言之就是一个 “封装打包” 的过程,它将所有二进制形式的目标文件和系统组件合成一个可执行文件,当然完成链接的过程也需要一个特殊的软件——链接器。

以上我们就大致了解了程序是如何将源文件转化为可执行程序的了。

2.运行环境

我们知道程序必须载入内存中,在有操作系统的环境中:一般这个由操作系统完成。而在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
 

那么运行的流程是什么样的呢?以下为程序运行的大致流程:

1. 程序的执行时便开始,接着便调用main函数。
2. 开始执行程序代码,这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
3. 终止程序,正常终止main函数;也有可能是意外终止。

那么这样我们也就大致了解了程序是如何运行的了。


以上就是所有关于编译与链接的全部内容了~~~

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

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

相关文章

算法之美:B+树原理、应用及Mysql索引底层原理剖析

B树的一种变种形式,B树上的叶子结点存储关键字以及相应记录的地址,同等存储空间下比B-Tree存储更多Key。非叶子节点不对关键字记录的指针进行保存,只进行数据索引 , 树的层级会更少 , 所有叶子节点都在同一层, 叶子节点的关键字从小到大有序排…

安装uim-ui插件不成功,成功解决

安装:这种安装,umi4 不支持,只有umi3才支持。而我发现官网现在默认使用的umi4。 yarn add umijs/preset-ui -D 解决:更改umi版本重新安装umi3 npm i ant-design/pro-cli3.1.0 -g #使用umi3 (指定umi3版本) pro create user-ce…

伪原创文章生成软件:自媒体文章写作好神器

自媒体的红利时代,许多人都纷纷参于其中,而文章写作是做自媒体的基本技能,但是随着技术的发展,如今,既使不会写作能力一样可以做起自媒体,方法就是利用伪原创文章生成软件来做内容的输出,其实伪…

【Vue3进阶】- 第2学堂小商城实战课程前言

该教程为进阶教程,如果你还不了解Vue3的基础知识,可以先前往Vue3基础教程,从入门到实战。 学习时遇到的任何疑问都欢迎在相应课文页面下方的问答区进行提问哦 我能学到什么? 编程写法千千万,实现需求是第一。 教程中…

如何在 Ubuntu 安装桌面环境

在 Ubuntu 上安装不同的桌面环境 如果你正在使用官方的 Ubuntu 发行版,它运行在 GNOME 上,那么你可以很容易地从默认的包管理器安装其他流行的桌面环境(DE)。让我们开始吧… 在 Ubuntu 上安装 KDE Plasma 如果你正在使用 GNOME…

8.6 循环神经网络的简洁实现

每个步长共用参数 加载数据 虽然 8.5节 对了解循环神经网络的实现方式具有指导意义,但并不方便。 本节将展示如何使用深度学习框架的高级API提供的函数更有效地实现相同的语言模型。 我们仍然从读取时光机器数据集开始。 import torch from torch import nn from…

面向对象:继承

文章目录 一、什么叫继承?二、单继承三、多继承3.1多继承的各种情况3.1.1一般情况3.1.1特殊情况(菱形继承) 四、菱形继承引发的问题4.1 问题1:数据冗余4.2 问题2:二义性(无法确定到底是访问哪个) 五、虚拟继承解决菱形…

PXE批量装centos7系统

1.环境准备: yum -y install tftp-server xinetd #安装并启用 TFTP 服务 #修改TFTP服务的配置文件 vim /etc/xinetd.d/tftp protocol udp # TFTP默认使用UDP协议 wait no # no表示客户机可以多台一起连接&…

JavaScript高级 —— 学习(一)

目录 一、作用域 (一)局部作用域 1.函数作用域 2.块作用域 (二)全局作用域 二、垃圾回收机制 GC (一)生命周期 1.内存分配 2.内存使用 3.内存回收 4.特殊情况——内存泄漏: 注意&…

【MySQL】数据库--表操作

目录 一、创建表 二、查看表 三、修改表 1. 添加字段--add 2.修改表名--rename to 3.修改列名--change 4.修改字段的数据类型--modify 5.删除字段(列)--drop 四、删除表 一、创建表 create [temporary]table[if not exists]table_name [([colu…

答题小程序功能细节揭秘:如何提升用户体验和满足用户需求?

答题小程序功能细节体现 随着移动互联网的快速发展,答题小程序成为了用户获取知识、娱乐休闲的重要平台。一款优秀的答题小程序不仅应该具备简洁易用的界面设计,更应该在功能细节上做到极致,以提升用户体验和满足用户需求。本文将从题库随机…

Java毕业设计-基于springboot开发的游戏分享网站平台-毕业论文+答辩PPT(附源代码+演示视频)

文章目录 前言一、毕设成果演示(源代码在文末)二、毕设摘要展示1、开发说明2、需求分析3、系统功能结构 三、系统实现展示1、系统功能模块2、后台登录2.1管理员功能模块2.2用户功能模块 四、毕设内容和源代码获取总结 Java毕业设计-基于springboot开发的…

类与对象中C++

加油!!! 文章目录 前言 一、类的6个默认成员函数 ​编辑 二、构造函数 1.概念 三、析构函数 1.概念 2.特性 四、拷贝构造函数 1.概念 2.特征 拷贝构造函数典型调用场景 五、赋值运算符重载 1.运算符重载 2.赋值运算符重载 赋值运算符重载格式…

Day24:私信列表、私信详情、发送私信

测试用户:用户名aaa 密码aaa 查询当前用户的会话列表;每个会话只显示一条最新的私信;支持分页显示。 首先看下表结构: conversation_id: 用from_id和to_id拼接,小的放前面去(因为两个人的对话应该在一个会…

如何使用剪映专业版剪辑视频

1.操作界面功能介绍 2.时间线的使用 拖动前端后端缩减时长,有多个素材可以拖动调节前后顺序拼接。 分割视频 删除

新零售SaaS架构:客户管理系统的应用架构设计

客户管理系统的应用架构设计 应用层定义了软件系统的应用功能,负责接收用户的请求,协调领域层能力来执行任务,并将结果返回给用户,功能模块包括: 客户管理:核心功能模块,负责收集和更新客户信息…

FPGA时钟资源详解(3)——全局时钟资源

FPGA时钟系列文章总览:FPGA原理与结构(14)——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 一、概述 全局时钟是 FPGA 中的一种专用互连网络,旨在将时钟信号分配到 FPGA 内各种资源的时钟输入处。这种设计…

探索数据库--------------mysql主从复制和读写分离

目录 前言 为什么要主从复制? 主从复制谁复制谁? 数据放在什么地方? 一、mysql支持的复制类型 1.1STATEMENT:基于语句的复制 1.2ROW:基于行的复制 1.3MIXED:混合类型的复制 二、主从复制的工作过程 三个重…

IMU评估产后腹直肌分离康复训练

腹直肌分离(Diastasis Recti Abdominis,DRA)是由腹部纤维联结组织——腹白线的过度伸张所致,这项研究的目标是通过惯性测量单元(IMU)感应器信号来分析产后康复。传统的康复方式通常包括针对性的物理疗法&am…

《QT实用小工具·一》电池电量组件

1、概述 项目源码放在文章末尾 本项目实现了一个电池电量控件,包含如下功能: 可设置电池电量,动态切换电池电量变化。可设置电池电量警戒值。可设置电池电量正常颜色和报警颜色。可设置边框渐变颜色。可设置电量变化时每次移动的步长。可设置…