编译器的过程,从源文件到.exe文件经过就几步,是如何进行的

2024-03-17 09:58

本文主要是介绍编译器的过程,从源文件到.exe文件经过就几步,是如何进行的,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

从一个.cpp文件到一个exe会经过如下几步

1.预处理

2.编译

3.汇编

4.链接

1:预处理阶段有预处理器进行,会将每一个.cpp(源文件(c语言程序和c++语言程序是一样的)预处理器会将所有源文件中的与预处       理指令进行处理,所谓的预处理执行就是  #开头的语句

      如#define    #include   #if 1  #endif     宏定义,头文件包含   条件偏移等等都是预处理指令

      #pragma once(加上头文件的开头,能够保证这个头文件的内容只被编译一次)上述等等都是最常见的预处理指令

vs可以配置预处理器生成预处理阶段生成的预处理文件.i文件

 设置好后点重新生成,可以看到给两个源文件都生成了.i文化

这是我Main.cpp文件中的内容

#include"taolaoda.h"
#include<stdio.h>
#define  LOG(x)  printf("%d\n",x)  
int main() {
    LOG(add(1, 2));
    LOG(sub(10, 20));
    LOG(mul(3, 5));
    LOG(div(3, 6));
    getchar();
}

这是我taolaoda.cpp文件中内容

int  add(int a, int b) { return a + b; }
int  sub(int a, int b) { return  a - b; }
int  mul(int a, int b) { return a * b; }
int  div(int a, int b) {
    if (0 == b) {
        return -1;
    }
    return a / b;
}

这是我们taolaoda.h我们的内容

#pragma once
int  add(int a,int b);
int  sub(int a,int b);
int  mul(int a, int b);
int  div(int a, int b);
 

打开Main.i,可以看到一开始就是把taolaoda.h文件中的内容复制到Main.i中了

这个文件有1万多行,因为#include<stdio.h>,可以看到后面本来源文件使用的是宏,全都替换成了定义的

所以#defien宏定义的效率为什么高,因为它在预处理阶段就替换了不会影响执行使其的效率

而且实现一个简单的功能如何封装成宏函数,而不是普通函数,也能实现模块化,而且不用给函数开辟堆栈,效率会更高

 

taolaoda.i文件几乎没有什么变化,因为根本没有taolaoda.cpp里面没有使用预处理指令

 

我将taolaoda.cpp中加一个条件偏移,和一个#Include包含taolaoda.h看看  在重新生成

 

可以看到taolaoda.i文件  现在我们可以更加清楚的知道#include包含只不过是文件的复制嘛,把某个文件复制到源文件中

对了设置成了预处理文件就编译不了必须设置回去才能编译

如果最后要调试运行,需要把上述的改动 改回去,不然生成不了obj文件的

2:汇编将是将预处理生成的.i文件作为输入,生成.asm汇编文件作为输出

可能有的人有些奇怪汇编文件不是.s为什么是.asm   linux下是.s Windows下是.asm

3:汇编就是将生产的.asm(汇编)作为输入 .obj文件作为输出,我们知道CPU只能是被二进制,汇编程序作为机器指令的助记符,只是给人看的,CPU识别不了,CPU只能是被二进制,汇编就是将汇编文件转换成二进制文件.obj  也称为目标文件

4:链接将多个.obj文件作为输入生成一个exe文化可执行文件作为输出

比如我们main函数所在的.obj文件上述了是需要使用taolaoda.obj文件中的函数,且在mian函数所在的.obj中声明了,链接器会去找其他.obj文件中找找到那个函数,然后将多个.obj文件中的东西复制到一个exe可执行文件中,我们需要使用其他文件中的函数和变量,这个就是链接器去找的,找到了虽有需要找到然后缝缝补补成一exe

 

链接器会将每个目标文件看成一组外部对象(全局的),每个外部对象看成内存中的一部分,链接器还会处理一些命名冲突

如果一个文件中不允许有两个外部对象名字一样,

 

预处理阶段由预处理器做将源文件作为输入,.i文件作为输出

编译阶段由编译器将,i文件作为输入,.asm文件作为输出

汇编阶段由汇编器将.asm文件作为输入,.obj文件作为输出

以上每个阶段文件生成数,与输出数相同,

链接器是将生成的多个obj文件补合成一个可执行文件

发送在编译期间的错误最容易找,发送链接阶段的错误很让通头痛(如果没有理解链接阶段做了什么)发送了链接错误

那就是噩梦

看我们引用其他文件中的一个外部变量 a,但是我在其他文件中没有定义,然后链接的时候就找到了,然后就给了一个链接错误

当然这是最简单的链接错误

 

如果想要跟加深入了解这写过程是如何做的,建议学习编译原理

 

这篇关于编译器的过程,从源文件到.exe文件经过就几步,是如何进行的的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/818609

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

遮罩,在指定元素上进行遮罩

废话不多说,直接上代码: ps:依赖 jquer.js 1.首先,定义一个 Overlay.js  代码如下: /*遮罩 Overlay js 对象*/function Overlay(options){//{targetId:'',viewHtml:'',viewWidth:'',viewHeight:''}try{this.state=false;//遮罩状态 true 激活,f

Solr 使用Facet分组过程中与分词的矛盾解决办法

对于一般查询而言  ,  分词和存储都是必要的  .  比如  CPU  类型  ”Intel  酷睿  2  双核  P7570”,  拆分成  ”Intel”,”  酷睿  ”,”P7570”  这样一些关键字并分别索引  ,  可能提供更好的搜索体验  .  但是如果将  CPU  作为 Facet  字段  ,  最好不进行分词  .  这样就造成了矛盾  ,  解决方法

利用matlab bar函数绘制较为复杂的柱状图,并在图中进行适当标注

示例代码和结果如下:小疑问:如何自动选择合适的坐标位置对柱状图的数值大小进行标注?😂 clear; close all;x = 1:3;aa=[28.6321521955954 26.2453660695847 21.69102348512086.93747104431360 6.25442246899816 3.342835958564245.51365061796319 4.87

Python:豆瓣电影商业数据分析-爬取全数据【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】

**爬取豆瓣电影信息,分析近年电影行业的发展情况** 本文是完整的数据分析展现,代码有完整版,包含豆瓣电影爬取的具体方式【附带爬虫豆瓣,数据处理过程,数据分析,可视化,以及完整PPT报告】   最近MBA在学习《商业数据分析》,大实训作业给了数据要进行数据分析,所以先拿豆瓣电影练练手,网络上爬取豆瓣电影TOP250较多,但对于豆瓣电影全数据的爬取教程很少,所以我自己做一版。 目

Python脚本:对文件进行批量重命名

字符替换:批量对文件名中指定字符进行替换添加前缀:批量向原文件名添加前缀添加后缀:批量向原文件名添加后缀 import osdef Rename_CharReplace():#对文件名中某字符进行替换(已完结)re_dir = os.getcwd()re_list = os.listdir(re_dir)original_char = input('请输入你要替换的字符:')replace_ch