深入理解计算机系统,源码到可执行文件翻译过程:预处理、编译,汇编和链接

1.前言

从一个高级语言到可执行程序,要经过预处理、编译,汇编和链接四个过程。大家可以思考下,为什么要有这样的过程?
在这里插入图片描述

我们学习计算机之处,就应该了解到,计算机能够识别的只有二进制语言(这是本身硬件特点决定的)。计算机刚诞生时,程序员写的就是二进制语言(机器语言),也就是0101的代码串。但机器语言的缺点也是非常明显的(和人类自然语言相差过大,难以理解,难以编写,难以维护)。

后来就发展出易于理解和编写的汇编语言,汇编语言是使用使用助记符和符号来代替机器码中的复杂二进制指令,提高了程序的可读性和可维护性,也降低了编写程序时的复杂程度。但汇编语言依然有其面临的问题,它依赖于硬件(不同CPU指令集不同,寄存器结构也不同),难以跨平台使用。比如如何把0101的机器码翻译成指令,这就与指令集有关。计算机组成原理这门课会将如何设计一个指令系统,感兴趣的请大家自行查阅资料。

基于汇编语言的一些问题,进一步诞生了高级语言,高级语言的特点是可读性更好,移植性也更好,更利于编写和维护。当然,其缺点就是高级语言无法并计算机直接执行,必须翻译成机器码后,才能被计算机执行。基于程序在执行之初,是否就要全部翻译,有编译型语言和解释型语言之分。自然,如python这样的解释型语言,代码是边解释成机器语言边执行,那么其效率自然低一些。与此相对,编译型语言因为在执行之初,就一次性把高级语言代码翻译成了计算机可以识别的机器码。那么其在执行时,花费的时间相对于解释型语言就少(相同的硬件环境下)。

2.翻译过程

言归正传,我们继续讲高级语言翻译成机器码的过程。前面已经提到从高级语言到机器码要经过四步。下面,我们对每一步做详细讲解。
在这里插入图片描述

1.预处理:

预处理之后,代码仍然是高级语言。预处理做了哪些东西呢? 头文件展开(这个过程中会检查头文件循环依赖)
宏替换(宏的本质是文本替换,所以这也是大家看到为什么一些程序员会把定义的宏值用括号给括上)
条件宏(根据预先设定的条件,决定后续编译哪些代码) 版本宏(和条件宏本质一样,只不过常用于隔离不同版本的代码)

……
2.编译过程:.i -> .s

编译过程就是把高级语言程序翻译成汇编语言。 .s文件里面就是汇编指令。这个编译是要经过词法分析和语法分析,具体请看 编译原理相关书籍。
编译器会把每个源文件都编译生成对应的.s文件,也会生成相应的符号表,存储在.s文件中。比如,一个函数修饰成inline了,并且编译器也根据用户建议把该函数给内联了,那么在符号表中是找不到该函数名的。内联的本质不是函数调用,而是把对应的代码嵌入到程序中,是函数展开。

3.汇编过程:.s->.o

.o文件里面已经二进制文件了,它还需经链接才能最终生成可执行文件 o文件叫可重定位目标文件,它是以地址零为链接起始地址进行链接的。
编译器将函数编译成二进制指令后,是从地址零可以将函数的指令序列存放到代码段。每个函数的入口地址都是从地址零开始往后偏移。

4.链接:

链接器将各个目标文件组装到一起,需要重新修改 各个目标文件中的变量或函数的地址,这个过程就是重定位。 链接器怎么知道 .o 重定位目标文件中
哪些函数或变量需要重定位呢?.o文件中实际是把需要重定位的符号手机起来,以section的形式保存到每个可重定位目标文件中了。

3 程序加载过程

最后讲一下,一个可执行文件被装载到内存,待执行的过程。大体分为以下几步:

1.给进程分配虚拟内存空间
2.创建虚拟地址到物理地址的映射,创建页表
3.加载代码段和数据段等数据,即将磁盘中的文件拷贝到物理内存中,并在页表中写入映射关系。
4.将可执行文件的入口地址写入到CPU的指令寄存器PC(PC中存放的就是下一步要执行的指令的地址)

在这里插入图片描述
图引用自 CSDN @汐 风

在这里插入图片描述
图引用自 CSDN @ Rye

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

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

相关文章

民安:助力提升城市安全水平

随着城市化进程的加速,平安城市的创建成为了社会治理的重要议题。为了解公众对平安城市创建的看法和评价,为提升城市安全水平提供参考,近期某市委托民安智库专业市场调查公司开展了一次安全感满意度调查。 本次调查围绕公共安全、个人安全、…

HTTP代理是什么,主要用来干嘛?

在探讨互联网通信和数据传输的广阔领域中,HTTP代理作为一个重要而广泛使用的工具,扮演着不可或缺的角色。本文将深入浅出地介绍HTTP代理的基本概念、工作原理及其主要应用场景。 一、HTTP代理的基本概念 HTTP代理,简而言之,是一…

“不可能三角”的“宿敌”,AI辅助技术撕开“第一道口子”

尽管,打破看得好病、看得起病和看得上病这个“不可能三角”,无法一蹴而就,但是在人工智能浪潮的推动下,“不可能”也在逐渐向“可能”转变。 近日,国家医保局在相关新闻发布会上表示,目前已编制发布17批立…

【Linux】剧幕中的灵魂更迭:探索Shell下的程序替换

🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 一念既出,万山无阻 目录 📖一、进程程序替换 1.替换的演示 ❓替换与执行流 ❓程序替换≠进程替换 2.替换的原理 …

【MySQL】数据库开发技术:内外连接与表的索引穿透深度解析

前言:本节内容主要讲解表的内连和外连以及索引的一部分。 注意: 索引是很重要的知识点。务必学习!!本节将会主要谈一谈什么是索引,如何理解索引。 以及怎么理解MySQL与磁盘的关系。 下面友友们开始学习吧! ps&#xff…

Matlab Simulink HDL Coder开发流程(三)— 验证从Simulink模型生成的HDL代码

验证从Simulink模型生成的HDL代码 一、什么是HDL Test Bench(测试台)二、简单的计数器模型三、验证方法四、生成HDL Test Bench生成VHDL Test Bench生成Verilog Test Bench代码 五、查看HDL Test Bench文件六、运行仿真和验证生成的HDL代码七、在目标设备…

设计模式:11、迭代器模式(游标)

目录 0、定义 1、迭代器模式的四种角色 2、迭代器模式的UML类图 3、示例代码 4、迭代器的next()方法与集合的get(int index)方法的效率对比(LinkedList为例) 0、定义 提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象…

基于SpringBoot的“招聘信息管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“招聘信息管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能结构图 系统首页界面图 企业招聘界面…

Linux高阶——1123—服务器基础服务器设备服务器基础能力

目录 1、服务器基础 1、服务器基本概述 2、服务器设计之初解决的问题 网络穿透 网络数据设备间的收发 3、服务器的类型C/S、B/S 2、服务器设备 将自己的服务器软件部署上线 3、代理服务器负载均衡,以及地址绑定方式 4、服务器的基础能力 1、服务器基础 1…

探索 Python 任务自动化的新境界:Invoke 库揭秘

文章目录 探索 Python 任务自动化的新境界:Invoke 库揭秘背景:为何选择 Invoke?什么是 Invoke?如何安装 Invoke?5个简单的库函数使用方法1. 定义任务2. 带参数的任务3. 运行 Shell 命令4. 任务参数化5. 列出任务 场景应…

docker部署nginx,并配置SSL证书

、拉取nginx镜像 docker pull nginx:latest 在此过程中会遇到网络的问题&#xff0c;导致镜像无法下载&#xff0c;这时候需要在服务器中配置下国内的镜像地址。下面包含近期最新的国内镜像&#xff0c;截至2024年11月27日&#xff1a; "https://<你的阿里云账号ID&…

使用NAS开启无纸化办公,Docker部署开源文档管理系统『Paperless-ngx』

使用NAS开启无纸化办公&#xff0c;Docker部署开源文档管理系统『Paperless-ngx』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 对于文案类的办公场景来说&#xff0c;手头堆放最多的可能就是各种文档文件&#xff0c;以及各种用过的打印废纸。 这么多年来&#xff0c;不管是领…

ES 基本使用与二次封装

概述 基本了解 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它提供了对海量数据的快速全文搜索、结构化搜索和分析功能&#xff0c;是目前流行的大数据处理工具之一。主要特点即高效搜索、分布式存储、拓展性强 核心功能 全文搜索:…

nextjs+nestjs+prisma写todolist全栈项目

技术栈 nextjsnestjsprisma所学知识 Nextjs组件渲染,状态,路由docker启动Mysql容器prisma操作Mysql(CRUD)允许跨域请求APITanStack Query异步状态管理fetch api服务器组件预请求数据nestjs 管道和异常处理检测id是否正整数Docker启动Mysql容器 compose.yml name: todoLis…

矩阵的拼接

矩阵的拼接分为横向拼接和纵向拼接 注意&#xff1a;横向拼接要求两矩阵行数相同&#xff0c;纵向拼接要求两矩阵列数相同 h o r z c a t horzcat horzcat和 v e r t c a t vertcat vertcat函数 h o r z c a t ( a , b ) horzcat(a,b) horzcat(a,b)将 a a a和 b b b横向拼接&a…

决策树——基于乳腺癌数据集与cpu数据集实现

决策树——乳腺癌数据实现 4.1 训练决策树模型,并计算测试集的准确率 1. 读入数据 from sklearn import datasets from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import confusion_matrix …

【ruby on rails】dup、deep_dup、clone的区别

一、区别 dup 浅复制&#xff1a;dup 方法创建对象的浅复制。 不复制冻结状态&#xff1a;dup 不会复制对象的冻结状态。 不复制单例方法&#xff1a;dup 不会复制对象的单例方法。 deep_dup 深复制&#xff1a;deep_dup 方法创建对象的深复制&#xff0c;递归复制嵌套的对象。…

PyTorch:神经网络的基本骨架 nn.Module的使用

神经网络的基本骨架 nn.Module的使用 为了更全面地展示如何使用 nn.Module 构建一个适用于现代图像处理任务的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;我们将设计一个针对手写数字识别&#xff08;如MNIST数据集&#xff09;的简单CNN模型。CNN非常适合处理图像数…

Java中使用FFmpeg拉取RTSP流

在Java中使用FFmpeg拉取RTSP流并推送到另一个目标地址是一个相对复杂的任务&#xff0c;因为Java本身并没有直接处理视频流的功能。但是&#xff0c;我们可以借助FFmpeg命令行工具来实现这个功能。FFmpeg是一个非常强大的多媒体处理工具&#xff0c;能够处理音频、视频以及其他…

【Qt】重写QComboBox下拉展示多列数据

需求 点击QComboBox时&#xff0c;下拉列表以多行多列的表格展示出来。 实现 直接上代码&#xff1a; #include <QComboBox> #include <QTableWidget> #include <QVBoxLayout> #include <QWidget> #include <QEvent> #include <QMouseEve…