“程序的编译+链接”,深入认识代码生成可执行程序的过程

news2024/10/6 16:21:12

目录

引入

 编译

预编译

编译

 汇编

链接

选项总结

记忆方法

运行环境


引入

博主认为学习本章内容,能够认识在代码跑的时候的'过程'。

首先,粗略笼统的认识程序运行过程的框架图。

 编译

其次,再进行细化,细化编译的过程,深入了解编译三个步骤,包含预编译/预处理、编译、汇编。了解链接与编译的交接,自然而然就豁然开朗了。

博主的想法是先告诉大家上述的三个步骤大致是干嘛的,然后由浅入深的理解。

预编译

预编译也可以叫预处理,具体样例:头文件的展开,#define定义的标识符常量转换(标识符转换成值),注释的删除等,第一步骤是文本操作。

向下我就要用Linux跟大家演示了,因为VS是集成开发环境,编译的过程细化是看不到的。

大致步骤:创建文件->编辑文件->编译三步骤

 

 

 这里的编译选项-E就涉及到编译步骤的选项了,-E是对文件进行预处理,-o 是output把预处理好的文件重定向到指定文件中,后缀设置成.i也是依照预处理后的文件属性规定。

然后我进入到test.i一探究竟!

 可以看到注释消失了(给代码玩家们看的,编译器又不看),标识符常量也被更换成了具体的值,而包含的头文件进行了展开,证明了预处理操作是进行文本操作。

编译

编译就是将预处理后的语言转换成汇编代码,汇编代码会经过语法分析、词法分析、语义分析、符号汇总这四个过程,使用-S选项进行编译,生成.s后缀的文件。

 test.s内容

 除了符号汇总大家都能理解,符号汇总汇总的是全局符号。

 汇编

汇编是将汇编码转换成二进制码,并且在这个汇编过程中还会形成符号表,符号表存放的是符号名和地址。-c选项是进行汇编,形成以.o为后缀的目标(object/obj)文件。

test.o的实际内容:

 形成符号表是要在链接时使用。

每一种文件的都有自己的组织方式,这里就要提到Linux下.o为后缀的文件,这种二进制内容经过汇编步骤的文件,是以elf格式组织的。

 

链接

把一个项目的所有文件(test.c、add.c)以及链接库合到一起,生成.exe为后缀的可执行程序。行动:1、合并段表;2、符号表的合并和重定位

实际上.exe文件在Linux环境下也是elf格式,elf格式就是分类分割不同的数据,相同数据在一起。

所以合并段表就是将不同文件的相同类型的数据合并到一起,合并方式还是类似于归类。

符号表的合并,字面意思将所有的符号表合并在一起,符号表的重定位也是因为向下方图第二个add的地址是无效地址(为了做演示,依据编译器不同而不同),所以就重定位为0x100为add的地址。

 当然如果第一个add函数没写,第二个add函数当然是一个无效的地址了,因为找不到add,所以这里编译器就会报链接错误。

 名字写错,例如大小写错误,也是一样的

 选项总结:

1.预处理 选项 gcc -E test.c -o test.i
预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件中。
2. 编译 选项 gcc -S test.c
编译完成之后就停下来,结果保存在test.s中。
3. 汇编 gcc -c test.c
汇编完成之后就停下来,结果保存在test.o中。

记忆方法:

选项是键盘上的ESC键,生成的文件后缀iso,相似于ios操作系统,但是只要记住目标文件(.o)是在自后就行了,s相当于一个滑坡,一个弯道,过了这个弯道就是目标.o。

运行环境

程序执行的过程:

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

书籍推荐:《程序员的自我修养》

谢谢大家阅读本章内容,欢迎大家在评论区留言讨论、补充、指错。让本章知识点内容更加的充实拓宽,谢谢!
 

 

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

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

相关文章

人工智能轨道交通行业周刊-第29期(2023.1.2-1.8)

本期关键词:站台限界测量机器人、智慧云巴、钢轨伸缩调节器、国铁集团会议、4D毫米波雷达、车道线检测1 整理涉及公众号名单1.1 行业类RT轨道交通中关村轨道交通产业服务平台人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道…

node.js+mysql博客全栈系统源码+数据库,含后台完整基础功能,小程序,web前台站点一键置灰,支持移动端适

一个 "开箱即用" 个人博客全栈系统项目!下载地址:node.jsmysql博客全栈系统源码数据库 🥯 预览 👀 前台预览 👀 管理端预览 🥯 v1.0.2 介绍 芒果’个人博客系统,包括前后台完整基…

Linux下buff/cache占用过大问题

当我们在命令行中执行free -h 查看内存时,发现buff/cache占用过大,导致其他软件没有内存可使用 从图上可以看出,buff/cache占用了1G多。 buff/cache是由于系统读写导致的文件缓存,没有及时释放。 解决方案:清理缓存 …

JWT JWT

JWT(JSON WEB TOKEN) JWT的组成 header(头部):中主要存储了两个字段 alg,typ。 alg表示加密的算法默认(HMAC SHA256),typ表示这个令牌的类型默认为JWT。 payload&#…

68、Learning Object-Compositional Neural Radi

简介 设计了一种新的双通路架构,其中场景分支编码场景几何和外观,而对象分支编码以可学习的对象激活码为条件的每个独立对象。为在严重杂乱的场景中生存训练,提出一种场景引导的训练策略,以解决遮挡区域的3D空间模糊性&#xff0c…

【ElasticSearch7.X】学习笔记(四)

【ElasticSearch7.X】学习笔记八、SpringData集成ElasticSearch8.1、框架8.1.1、SpringData8.1.2、Spring Data Elasticsearch8.2、搭建8.2.1、maven引入8.2.2、编写配置8.2.3、编写config8.2.4、Product类8.2.5、dao8.2.6、索引操作8.2.7、文档操作8.2.8、文档搜索八、SpringD…

基于 Tensorflow 2.x 从零训练 15 点人脸关键点检测模型

一、人脸关键点检测数据集 在计算机视觉人脸计算领域,人脸关键点检测是一个十分重要的区域,可以实现例如一些人脸矫正、表情分析、姿态分析、人脸识别、人脸美颜等方向。 人脸关键点数据集通常有 5点、15点、68点、96点、98点、106点、186点 等&#x…

ccc-sklearn-14-朴素贝叶斯(2)

文章目录sklearn中的其他贝叶斯算法一、MultinomialNB多项式贝叶斯sklearn中的MultinomialNB二、BernoulliNB伯努利朴素贝叶斯三、ComplementNB补集朴素贝叶斯案例:贝叶斯做文本分类sklearn中的其他贝叶斯算法 一、MultinomialNB多项式贝叶斯 基于原始的贝叶斯理论…

【openGauss实战2】客户端连接工具及配置

📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA工作经验 一位上进心十足的【大数据领域博主】!😜&#x1f61…

shell第七天练习

awk题目: 1、获取根分区剩余大小 2、获取当前机器ip地址 3、统计出apache的access.log中访问量最多的5个IP 4、打印/etc/passwd中UID大于500的用户名和uid 5、/etc/passwd 中匹配包含root或net或ucp的任意行 7、请打印出/etc/passwd 第一个域,并且在第一…

广度优先搜索BFS进阶(一):多源BFS、优先队列BFS、双端队列BFS

一、多源BFS 在上一篇博客:广度优先搜索BFS基础中,我们接触到的BFS均是单起点(单源)的,但是对于某一些问题,其有多个起点,此类问题我们称为多源BFS问题。先思考下面一道例题: 1.腐…

类加载,类初始化,对象创建过程总结

总结&#xff1a;假如一个类还未加载到内存中&#xff0c;那么在创建一个该类的实例时&#xff0c;具体过程是怎样的&#xff1f;父类的类构造器<clinit>() -> 子类的类构造器<clinit>() -> 父类的成员变量和实例代码块 -> 父类的构造函数 -> 子类的成…

Go第 11 章 :面向对象编程(下)

Go第 11 章 &#xff1a;面向对象编程(下) 11.1 VSCode 的使用 11.1.1 VSCode 使用技巧和经验 11.2 面向对象编程思想-抽象 11.2.1 抽象的介绍 我们在前面去定义一个结构体时候&#xff0c;实际上就是把一类事物的共有的属性(字段)和行为(方法)提取 出来&#xff0c;形成一…

手把手教你图文并茂windows10安装VMware创建CentOS-7-x86_64运行linux系统

VMware是什么 VMWare (Virtual Machine ware)可以使你的计算机上同时运行几个系统、例如windows、DOS、LINUX等同时存在&#xff0c;可以将这些系统像程序似的随时切换&#xff0c;并且不会影响主系统&#xff0c;所有系统共享一个IP。 下载 VMware官网 安装 网上搜索一个序…

LeetCode栈和队列经典例题

本期博客给大家带来了几道经典栈和队列题&#xff0c;吃透它简直易如反掌~1.括号匹配问题题目地址&#xff1a;20. 有效的括号 - 力扣&#xff08;Leetcode&#xff09;解题思路&#xff1a;在这里我们创建一个栈&#xff0c;每次将字符入栈之前先对比栈顶元素是否相同&#xf…

蓝桥杯嵌入式之 LED 闪烁

这篇文章将详细为大家介绍如何实现 LED 闪烁。 我们使用的是 HAL 库。 文章目录前言一、STM32CubeMX配置:二、LED 原理图&#xff1a;三、LED闪烁 讲解&#xff1a;1. HAL_GPIO_WritePin 函数&#xff1a;用于操作 *GPIO* 电平。2.HAL_Delay函数&#xff1a;作为毫秒级延迟的函…

【消息队列】Centos7 虚拟机安装 RocketMQ 及启动控制台

文章目录前言目的注意点官网虚拟机1. 环境变量2. 安装并启动rocketmq3. 安装docker4. docker拉取并运行rocketmq-dashboard5. 关闭防火墙6. 宿主机查看控制台7. 关闭虚拟机的进程后记前言 目的 模拟在服务器上运行RocketMQ&#xff0c;并且有控制台的能力。以后本地window可以…

【自学C++】C++变量作用域

C变量作用域 C变量作用域教程 C 中的一个 变量 或 常量 在程序中都有一定的作用范围&#xff0c;我们称之为作用域。C 变量作用域可分为局部作用域和全局作用域。 C局部变量 在 函数 内部声明/定义的变量叫局部变量&#xff0c;局部变量的作用域仅限于函数内部。同时&#…

Linux应用编程---8.共享内存

Linux应用编程—8.共享内存 ​ 共享内存是进程之间通讯的方式。大概原理是先申请一块共享内存&#xff0c;然后通过“映射”&#xff0c;映射到进程中。进程中读写这块被映射过来的内存&#xff0c;共享内存也会随之改变&#xff0c;同理其它进程也能做相同的操作。所以&#…

dubbo源码实践-protocol层例子

1 概述本文提供了基于protocol层的一个客户端、服务端代码例子。从dubbo 2.7的架构图上可以看到protocol层上在Remoting层之上的&#xff0c;个人理解Protocol层不在讨论客户端和服务端的概念了&#xff0c;开始讨论服务提供者和服务消费者的概念了。参考上一篇dubbo源码实践-p…