程序的编译与链接(C语言为例) #代码写好后到运行期间要经过怎样的过程呢?# 粗略版 #

news/2024/5/11 5:07:44/文章来源:https://blog.csdn.net/Wennytime/article/details/128943129

编译与链接

  • 前言
  • 程序的环境
  • 程序的编译与链接
  • 写在最后


前言

每当我们运行一段代码时,编译器都会自动的帮我们编译代码并将代码转换为一个二进制可执行文件(.exe), 有了这个可执行文件,便可以执行我们写的程序了。那么编译器对代码的编译以及生成可执行程序的过程是怎样的呢?这个问题便是本文章将要探讨的。


程序的环境

ANSI C的任何一种实现中,存在两个不同的环境,一种是翻译环境,一种是执行环境

  • 翻译环境:在这个环境中源代码被转换为可执行的机器指令;
  • 执行环境:这个环境用于实际执行代码。

补充:

在这里插入图片描述

程序的编译与链接

首先看看 翻译环境 的简图:
在这里插入图片描述

  • 组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。
  • 每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
  • 链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索序员个人的程序库,将其需要的函数也链接到程序中。

编译本身也分为几个阶段:
预编译 —> 编译 —> 汇编

在这里插入图片描述

  • 预编译(预处理)

预处理阶段要做的事情主要是这些:

  1. #include 头文件的包含;
  2. #define定义符号的替换和删除;
  3. 注释的删除。

接下来在linux中用gcc编译器对一段代码进行预处理,如下:

在这里插入图片描述
预处理过后,我们观察test.i这个预编译后的文件:

指令:gcc -E test.c -o test.i

在这里插入图片描述

可以看到,代码一下子膨胀了许多,这正是因为头文件被包含进来了,当来原先的#define与注释也不见了。


  • 编译

编译阶段是将C语言代码翻译成汇编代码, 其过程有:

  1. 语法分析;
  2. 词法分析;
  3. 语义分析;
  4. 符号汇总

符号汇总就是将相关的函数,以及全局变量汇总:

例如以下代码汇总后客观图:

在这里插入图片描述
将上述代码编译后:

指令:gcc -S test.c -o test.s

在这里插入图片描述

可以看到,C语言被翻译成了汇编代码。


  • 汇编
  1. 汇编是将汇编代码翻译成了二进制指令(存放目标文件),也就是生成目标文件的一步(test.o
  2. 汇编使汇总的符号形成符号表,也就是每个符号对应一个地址。

如下:
在这里插入图片描述

就将上述代码汇编,我们来看看test.o是不是二进制文件呢?

指令:gcc -c test.c -o test.o

在这里插入图片描述

可以看到,的确是一些二进制乱码。


通过编译的一系列过程后,接下来就是链接了

链接的相关过程有:
1. 合并段表(这里不解释,需了解细读《程序员的自我修养》这本书,里面对整个编译链接部分都有很详细的讲解)
2. 符号表的合并和重定位。

这里只讲解符号表的合并:

  1. 在上面所探讨的编译过程,每一个文件都会形成自己的目标文件,在汇编这一步,又会形成自己的符号表;
  2. 如果一个程序有两个文件,就会有两个符号表,所以,符号表的合并,就是链接的一步。

例如test1.c文件和test2.c文件的符号表合并过程:

在这里插入图片描述

最终,通过链接器和链接库将各个目标文件链接后形成可执行文件。


程序执行的过程:

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

写在最后

如果说,你对这一块特别感兴趣,想继续深入,你可以读《程序员的自我修养》这本书,这本书里对这一块的知识有很详细的解析。

感谢阅读本小白的博客,错误的地方请严厉指出噢!

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

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

相关文章

基于风光储能和需求响应的微电网日前经济调度(Python代码实现)【1】

目录 1 概述 2 知识点及数学模型 3 算例实现 3.1算例介绍 3.2风光参与的模型求解 3.3 风光和储能参与的模型求解 3.5 风光储能和需求响应都参与模型求解 3.6 结果分析对比 4 Python代码及算例数据 1 概述 近年来,微电网、清洁能源等已成为全球关注的热点…

数智化转型赋能企业,端看低代码如何发展

随着大数据、云计算、区块链等新兴技术的广泛运用, 现代企业在生产经营中产生的大量数据与信息逐渐成为发展的核心资产。与传统生产要素一起共同创建新的经济范式, 标志着我国经济发展正式迈入数字经济时代。 数字经济的快速崛起促使产业升级不断加速&am…

ASEMI整流模块MDQ75-16封装,MDQ75-16大小

编辑-Z ASEMI整流模块MDQ75-16参数: 型号:MDQ75-16 最大重复峰值反向电压(VRRM):1600V 最大RMS电桥输入电压(VRMS):1700V 最大平均正向整流输出电流(IF)…

Java IO流 序列化流 ObjectOutputStream ObjectInputStream

Java IO流 打印流 PrintStream PrintWriter Java IO流 序列化流 ObjectOutputStream ObjectInputStream Java IO流 缓冲流 BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter Java IO流 字符流 目录拷贝 Java IO流 字符流 FileWriter Java IO流 字符流 …

Sentinel服务熔断和流控

简介Sentinel随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。源…

Java基础学习笔记(二十)—— 多线程(2)

多线程1 线程池1.1 线程状态1.2 线程池基本原理1.3 创建线程池1.4 任务拒绝策略2 共享变量的问题与解决2.1 存在的问题2.2 Volatile解决2.3 synchronized解决3 原子性3.1 原子性的实现(synchronized)3.2 AtomicInteger3.3 悲观锁和乐观锁4 并发工具类4.1…

算法 | 动态规划 | 系列题目讲解(思路记录part.1)

文章目录字符串分割三角矩阵路径总数最小路径和字符串分割 问题描述 给定一个字符串和一个词典dict,确定s是否可以根据词典中的词分成 一个或多个单词。 比如,给定 s “leetcode” dict [“leet”, “code”] 返回true,因为"leetcode…

吾剑未尝不利,国内Azure平替,科大讯飞人工智能免费AI语音合成(TTS)服务Python3.10接入

微软Azure平台的语音合成(TTS)技术确实神乎其技,这一点在之前的一篇:含辞未吐,声若幽兰,史上最强免费人工智能AI语音合成TTS服务微软Azure(Python3.10接入),已经做过详细介绍,然则Azure平台需要信用卡验证,有一定门槛&…

基于Apache Maven构建多模块项目

title: 基于Apache Maven构建多模块项目 date: 2022-04-10 00:00:00 tags: Apache Maven多模块 categories:Maven 介绍 多模块项目由管理一组子模块的聚合器 POM 来构建。在大多数情况下聚合器位于项目的根目录中,并且必须是 pom 类型的项目。子模块是常规的 Mave…

CNN网络:ResNet(四)

ResNet论文[https://arxiv.org/pdf/1512.03385.pdf]。RestNet网络结构ResNet在2015年被提出,在ImageNet比赛classification任务上获得第一名,因为它“简单与实用”并存,之后很多方法都建立在ResNet50或者ResNet101的基础上完成的,…

手机逻辑系统(2)---逻 辑 音 频 电 路

第二节 逻 辑 音 频 电 路 逻辑音频电路在手机电路中占有重要的地位,它是手机系统的心脏。 逻辑音频电路包含无线通信呼叫处理、音频处理、数字语音处理、射频逻辑接口电路、各种射频功能控制、电源管理和用户接口模组等。 任何一部手机的逻辑音频电路部分都包含以上的一些功能…

1.2.4存储结构-磁盘管理:磁盘优化分布存储、磁盘优化分布存储例题

1.2.4存储结构-磁盘管理:磁盘优化分布存储、磁盘优化分布存储例题磁盘优化分布存储磁盘优化分布存储 假设某磁盘的每个磁道划分成11个物理块,每块存放1个逻辑记录。逻辑记录R0,R1,…,R9,R10存放在同一个磁…

将U盘制作为启动盘

将U盘制作为启动盘 制作之前需要先保证U盘中没有重要的文件,因为制作时会将已有文件删除 1 安装制作软件【wePE】 ①官网选择对应PE版本下载安装 官网下载地址:http://www.wepe.com.cn IT天空的U盘装机助理:https://www.itiankong.net/thread-357573-1…

Ubuntu18 安装python3.7及多版本切换

1.安装3.7添加源sudo add-apt-repository ppa:deadsnakes/ppa检查更新sudo apt-get update 安装python3.7sudo apt-get install python3.72.使用 update-alternatives 来为整个系统更改Python 版本查看python替代版本信息~$ update-alternatives --display python但是结果为upd…

数字化发展趋势:打破企业边界,实现产业互联

据中欧商业在线发布的《2022未来管理人才白皮书》显示,在参加调研的1000家企业中,有77%的企业已经在公司业务中运用了数字化技术;更有7%的企业表示将在更深层面推进数字化转型工作。 当企业在业务层面完成数字化转型,下一步会走向…

知识图谱简介

知识图谱简介 知识图谱,是结构化的语义知识库,用于迅速描述物理世界中的概念及其相互关系,通过知识图谱能够将Web上的信息**、数据以及链接关系聚集为知识,使信息资源更易于计算、理解以及评价,并能实现知识的快速响应…

Keil中代码的颜色设置 ( 很 全 )[通俗易懂](转载)

https://cloud.tencent.com/developer/article/2081534Keil中代码的颜色设置 ( 很 全 )[通俗易懂]发布于2022-08-25 12:26:13阅读 1.8K0大家好,又见面了,我是你们的朋友全栈君。因为长时间要编程,对于keil上的黑字白底,如果看久了…

Python实现的通讯录

"为何表情,要让这世界安排?"诶,我们也对python的一些基础语法有了一定能的了解了。并且在这基础上,学习了python中的文件操作,那么有了这些东西以后啊,我们能做什么呢?或许对很多数据…

揭秘PPTC(自恢复保险丝)的四大使用原则

PPTC自恢复保险丝有贴片式以及插件式两种,封装形式多样,型号齐全,那么,在使用过程中,应该要注意什么?你知道吗?接下来,优恩小编将为你揭秘PPTC(自恢复保险丝)的四大使用原则。一、规…

Spring boot项目开发实战一(环境搭建)

技术栈选型 最近在实习好久没时间做过项目了,本次将借用公司的技术完成一个基于spring boot的实战项目,同时也巩固spring的相关知识。项目大体是一个后台管理系统,没有前台,用于数据分析和可视化。如下是初步的可视化界面&#x…