(3)C程序可执行文件的生成过程

news2025/1/16 21:39:54
原文链接:https://www.jianshu.com/p/b7e44f749211
一、可执行文件的生成

我们先通过一个简单C程序,回顾一下可执行文件的生成过程。

                        ​​​​​​​        ​​​​​​​        

可执行文件的生成过程如下图:

如图,可执行文件的生成需要经过预处理、编译、汇编和链接这4个过程。其中:

  • 预处理的工作:
  • 删除 #define 并展开宏定义
  • 处理所有的条件预编译指令,如 "#if","#ifdef","#endif"等
  • 插入头文件到 "#include" 处,可以递归方式进行处理
  • 删除所有的注释
  • 添加行号和文件名标识,以便编译时编译器产生调试用的行号信息
  • 保留所有 #pragma 编译指令(编译器需要用)
    命令示例如下:
  • gcc -E hello.c -o hello.i

经过预编译处理后,得到的是预处理文件(如,hello.i),它还是一个可读的文本文件,但不包含任何宏定义。

  • 编译的工作

编译过程就是将预处理后得到的预处理文件(如hello.i)进行词法分析、语法分析、语义分析、优化后,生成汇编代码文件。
经过编译后,得到的汇编代码文件(如,hello.S)还是一个可读的文本文件。
命令示例如下:

  • gcc -S hello.i -o hello.s
  • gcc -S hello.c -o hello.s
  • 汇编的工作

汇编器将编译得到的汇编代码文件转换成机器指令序列。
汇编的结果是一个可重定位目标文件(如,hello.o)其中包含的是不可读的二进制代码。
命令示例如下:

  • gcc -c hello.s -o hello.o
  • gcc -c hello.c -o hello.o
  • as hello.s -o hello.o
  • 链接的工作

链接过程将多个可重定位目标文件合并以生成可执行目标文件。
命令示例如下:

  • gcc -static -o myproc main.o test.o
  • ld -static -o myproc main.o test.o
二、链接的好处

学习链接之前,可能会有疑问,链接有什么好处?
其实链接的概念可以追溯到最早程序员用机器语言编写程序的时期。
来看下图,假设穿孔表示0,未穿孔为1,且 0010代表跳转jmp

        ​​​​​​​        ​​​​​​​        ​​​​​​​        

如果要在第5条指令前加入指令,则程序员就得重新计算jmp指令的目标地址(重定位),然后重新打孔。由此可以看到,这样很繁琐。
后来汇编语言的出现后,程序员用助记符表示操作码,用符号表示位置,用助记符表示寄存器,如下图:

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​


如图,可见,如果jmp L0 和 sub C之间加入了新的指令,则只要重新确定sub C指令的地址,再填入L0即可。而这个重定位的工作就是在链接的过程中完成的。

此外,链接还有如下好处:

  • 模块化
  • 一个程序可以分成很多源程序文件;
  • 可构建公共函数库,如数学库,标准C库等。以便代码重用,提高开发效率。
  • 效率高
  • 时间上,可分开编译:只需要重新编译修改的源程序文件,然后重新链接;
  • 空间上,无需包含共享库所有代码:源文件中无需包含共享库函数的源码,只要直接调用即可(如,只要直接调用printf() 函数,无需包含其源码),另外,可执行文件和运行时的内存中只需包含所调用函数的代码,而不需要包含整个共享库。
三、链接的步骤

再来看个C程序的例子:

通过命令生成可执行程序:

gcc -O2 -g -o p main.c swap.c

其生成过程如下图:

其中,链接的步骤如下

        1. Step-1:符号解析

程序中有定义和引用的符号(包括变量和函数等)

void swap() {...}  /* 定义符号swap */
swap();              /* 引用符号swap */
int *xp = &x;        /* 定义符号xp,引用符号x */

编译器将定义的符号存放在符号表中。
符号解析就是将符号的引用和符号的定义建立关联

        2. Step-2:重定位
  • 将多个代码段与数据段分别合并为一个单独的代码段和数据段
  • 计算每个定义的符号在虚拟地址空间中的绝对地址
  • 将可执行文件中的符号引用处的地址修改为重定位后的地址信息

这个步骤可用下图来简单描述:



原文链接:https://www.jianshu.com/p/b7e44f749211
 

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

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

相关文章

Java学习路线及自我规划

荒废了一段时间,这段时间的总结开始了JavaWeb的学习但是困难重重,例如Maven,Vue的路由等,所以我反省了一段时间,因为基础薄弱,加之学习的资源是速成视频,导致大厦将倾的局面(也算不上…

为什么如果重写了某个类的equals方法,还必须重写对应的hashcode方法?

为什么如果重写了某个类的equals方法,还必须重写对应的hashcode方法? 答: 保证equals相同的两个对象hashcode必须相同的原则。不重写hashcode方法的的话,若用hashmap/hashset等散列表存储这个类,可能会出现两个相同对…

IDEA上配置Maven环境

1.选择IDEA中的Setting 2.搜索maven 3.设置IDEA使用本地安装的Maven,并修改配置文件路径 配置文件,本地仓库,阿里云仓库配置及路径教程 在IDEA上配置完成。

java中http调用组件深入详解

目录 一、前言 二、http调用概述 2.1 什么是http调用 2.1.1 http调用步骤 2.2 HTTP调用特点 2.3 HTTP调用应用场景 三、微服务场景下http调用概述 3.1 微服务开发中http调用场景 3.2 微服务组件中http的应用 四、常用的http调用组件 4.1 java中常用的http组件介绍 4…

输入输出重定向,追加重定向(Linux)

文章目录 一、输出重定向二、追加重定向三.输入重定向总结 一、输出重定向 我们在使用echo内容时,会把内容显示在显示器上。 echo自动换行。 我们如果输入 echo “hello linux” >file.txt 我们运行一下就会发现系统中多了一个file.txt的文件,如果这…

【C++打怪之路Lv3】-- 类和对象(上)

🌈 个人主页:白子寰 🔥 分类专栏:C打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~ 💡 坚持创作博文(平均质量分82)&#…

C++必修:类与对象(一)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C学习 贝蒂的主页:Betty’s blog 1. 面向过程与面向对象 1.1. 面向过程 我们之前学习的C语言就是一种面向过程的语…

plsql 新建sql窗口 初始化慢的问题

问题描述: 新建sql窗口当sql语句多的情况下初始化很慢。 解决方法: 采用导入表的方式。 具体方式 工具->导入表->sql插入。 使用命令窗口 导入文件,然后点击导入按钮。

【力扣 Hot100 | 第七天】4.22(找到字符串中所有字母异位词)

文章目录 2.找到字符串中所有字母异位词2.1题目2.2解法:滑动窗口2.2.1解题思路2.2.2代码实现 2.找到字符串中所有字母异位词 2.1题目 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺…

Spring Security认证流程分析

我自己的思路 先分别实现 userdetailsService,userDetails,passwordEncoder三个接口, 然后就是写登录逻辑 本文章用的是继承UsernamePasswordAuthenticationFilter这个接口 因为这个框架默认登录逻辑是在这里面的,里面的核心就是…

vivado 使用“链路 (Links)”窗口查看和更改链路设置

使用“链路 (Links) ”窗口查看和更改链路设置 创建链路后 , 就会将其添加到“ Links ”视图 ( 请参阅下图 ) 中 , 该视图是更改链路设置和查看状态的主要方法 , 也是最佳方法。 “ Links ”窗口中的每一行都对应 1 …

018基于SSM的音乐系统网站

018基于SSM的音乐系统/网站 开发环境: Jdk7(8)Tomcat7(8)MysqlIntelliJ IDEA(Eclipse)Maven 数据库: MySQL 技术: SpringSpring mvcMybatisJqueryVideo jsJSPJSTLEasyUI 适用于: 课程设计,毕业设计,学习…

航拍图像拼接 | 使用C++实现的无人机航拍图像拼接

项目应用场景 面向无人机航拍图像拼接场景,项目使用 C 实现,使用 harris 角点查找特征点 非极大值抑制,由于航拍图像没有严重的尺度旋转变化,使用了 berief 描述子,然后使用 RANSAC 求 H,最后进行图像拼接…

python入门完结篇(6)

插入: 1.使用append的方法,使用append往列表末尾新增一个元素。此处的append的是搭配列表对象来使用的,而不是作为一个独立的函数. 而 type print input len自定义函数都是独立的函数,不用搭配任何对象. 而这种需要搭配对象(变量&#xff09…

Ubuntu Mysql修改密码时遇到的问题

参考: ubuntu18.04 首次登录mysql未设置密码或忘记密码解决方法_ubuntu中mysql设置密码-CSDN博客 1. use mysql; #连接到mysql数据库 2. update mysql.user set authentication_stringpassword(123456) where userroot and Host localhost; #修改密码123456是密码…

解决iOS开发不能使用HTTP请求的问题

苹果公司在iOS9中升级了应用网络通信安全策略,默认推荐开发者使用HTTPS协议来进行网络通信,并限制HTTP协议的请求。为了解决这个问题,我们需要在info.plist文件中增加如下配置来实现广告的网络访问:(信任HTTP请求&…

【算法基础实验】图论-构建无向图

构建无向图 前提 JAVA实验环境 理论 无向图的数据结构为邻接表数组,每个数组中保存一个Bag抽象数据类型(Bag类型需要专门讲解) 实验数据 我们的实验数据是13个节点和13条边组成的无向图,由一个txt文件来保存,本…

数字旅游引领智慧化浪潮:科技创新重塑旅游体验,智慧服务打造旅游新高度

在科技飞速发展的今天,数字旅游正以其独特的魅力引领着智慧化浪潮,深刻改变着旅游行业的面貌。数字技术的广泛应用,不仅为旅游行业注入了新的活力,也极大地提升了旅游体验的品质。科技创新与智慧服务的融合,正推动着旅…

如何写好代码?

文章目录 前言内容代码应当易于理解命名注释格式循环和逻辑设计函数设计类其它(编程规范、静态检查工具)重构 前言 在软件开发领域,写好代码是至关重要的一环。不论是在学校学习的学生,刚刚毕业的应届生,还是刚步入企…

迁移学习基础知识

简介 使用迁移学习的优势: 1、能够快速的训练出一个理想的结果 2、当数据集较小时也能训练出理想的效果。 注意:在使用别人预训练的参数模型时,要注意别人的预处理方式。 原理: 对于浅层的网络结构,他们学习到的…