编译器的过程,从源文件到.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

相关文章

将Mybatis升级为Mybatis-Plus的详细过程

《将Mybatis升级为Mybatis-Plus的详细过程》本文详细介绍了在若依管理系统(v3.8.8)中将MyBatis升级为MyBatis-Plus的过程,旨在提升开发效率,通过本文,开发者可实现... 目录说明流程增加依赖修改配置文件注释掉MyBATisConfig里面的Bean代码生成使用IDEA生

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应