首页 > 其他分享 >【c语言】编译过程详解

【c语言】编译过程详解

时间:2024-05-03 15:45:20浏览次数:29  
标签:文件 语言 代码 链接 编译 编译器 详解 hello

机器无法理解我们编写的C语言,
而编译就是将面向人类的高级语言转换成为面向机器的机器语言的过程,
图1是GCC编译器进行编译的过程,编译时主要分为了4个阶段,
每个阶段的具体作用将在接下来进行介绍。

图1

注:预处理中的cpp不是 c plus plus,而是c pre-process

Part1 预处理

命令:gcc -E hello.c -o hello.i

编译过程的第一步预就是预处理,预处理结束后会产生一个后缀为(.i)的临时文件,这一步由预处理器完成。
预处理器主要完成以下任务。

1.1 头文件展开


#include <stdio.h> :在系统指定路径下寻找stdio.h;

#include "stdio.h" :在当前路径下寻找stdio.h 如果找不到则在系统指定路径下寻找stdio.h。

1.2 条件编译

根据不同情况编译不同代码、产生不同目标文件的机制,称为条件编译。
条件编译是预处理程序的功能,不是编译器的功能;

这些操作都是在预处理阶段完成的,多余的代码以及所有的宏都不会参与编译,不仅保证了代码的正确性,还减小了编译后文件的体积;

条件编译主要处理内容为:#if#ifdef#ifndef, #if defined(AAA), #if defined AAA

1.3 #define替换

将宏定义的常量或函数进行替换。

Part2编译

命令:gcc -S hello.c -o hello.s

C 中的编译阶段使用内置编译器软件将 (.i) 临时文件转换为具有汇编级指令(低级代码)的汇编文件 (.s)。
为了提高程序的性能,编译器将中间文件转换为程序集文件;

汇编代码是一种简单的英文语言,用于编写低级指令(在微控制器程序中,我们使用汇编语言)。
整个程序代码由编译器软件一次性解析(语法分析),并通过终端窗口告诉我们源代码中存在的任何语法错误或警告。

Part3汇编

命令:gcc -c hello.c -o hello.o

使用汇编程序将程序集级代码(.s 文件)转换为机器可理解的代码(二进制/十六进制形式)。
汇编程序是一个预先编写的程序,它将汇编代码转换为机器代码。它从程序集代码文件中获取基本指令,并将其转换为特定于计算机类型(称为目标代码)的二进制/十六进制代码;

生成的文件与程序集文件同名,在 DOS 中称为扩展名为 .obj的对象文件,在 UNIX 操作系统中扩展名为 .o

如图2显示了组装阶段如何工作的示例。程序集文件 hello.s 将转换为具有相同名称但扩展名不同的对象文件 hello.o

图2

Part4链接

命令:gcc hello.c -o hello

链接是将库文件包含在我们的程序中的过程。
库文件是一些预定义的文件,其中包含机器语言中的函数定义,这些文件的扩展名为.lib
一些未知语句写入我们的操作系统无法理解的对象 (.o/.obj) 文件中。
你可以把它理解为一本书,里面有一些你不知道的单词,你会用字典来找到这些单词的含义。
同样,我们使用库文件来为对象文件中的一些未知语句赋予意义。
链接过程会生成一个可执行文件,其扩展名为 .exe 在 DOS 中为 .out,在 UNIX 操作系统中为 .out

如上图2,显示了链接阶段如何工作的示例,我们有一个具有机器级代码的对象文件,它通过链接器传递,链接器将库文件与对象文件链接以生成可执行文件。

Part5结论

C中的编译过程也称为将人类可理解代码(C程序)转换为机器可理解代码(二进制代码)的过程;

C语言的编译过程包括四个步骤:预处理、编译、汇编和链接;

预处理器执行删除注释、宏扩展、文件包含。这些命令在编译过程的第一步执行;

编译器可以提高程序的性能,并将中间文件转换为汇编文件;

汇编程序有助于将汇编文件转换为包含机器代码的对象文件;

链接器用于将库文件与对象文件链接。这是编译中生成可执行文件的最后一步。

原创:杰尼 指尖动听知识库(wx)

标签:文件,语言,代码,链接,编译,编译器,详解,hello
From: https://www.cnblogs.com/o-O-oO/p/18171221

相关文章

  • Linux下ffmpeg库的编译链接
    /usr/bin/ld:/usr/local/ffmpeg/lib/libavformat.a(aviobuf.o):infunction`ff_crc04C11DB7_update':/home/ann/FFmpeg/ffmpeg/libavformat/aviobuf.c:568:undefinedreferenceto`av_crc_get_table'/usr/bin/ld:/home/ann/FFmpeg/ffmpeg/libavformat/aviobuf......
  • iptables使用详解(centos7)
    iptables使用详解(centos7)小百菜已于2024-03-2114:40:02修改阅读量7.2k收藏22点赞数2文章标签:iptables限速版权GitCode开源社区文章已被社区收录加入社区我们需要安装iptables-services,用来启动和停止iptables服务防火墙配置文件/etc/sysconfig/iptables查......
  • C语言解析FLM(ELF)格式文件
    代码下载:https://gitee.com/jhembedded/flmparse 写这篇博客的目的是因为最近在做一个STM32的离线编程器,离线下载需要用到FLM文件的下载算法,所以实现了一下提取FLM文件中下载算法的C程序。有关ELF格式的详细说明可查看这个文件:http://flint.cs.yale.edu/cs422/doc/ELF_Format.......
  • 详解csrf(跨站请求伪造)
    1.什么是csrf(csrf攻击原理)?用户正常访问A网站,A网站设置cookie被用户浏览器保存用户不关闭浏览器,直接访问恶意网站,该恶意网站内隐藏式内嵌了A网站接口的请求链接触发该请求链接,自动携带浏览器保存的cookie,请求成功。2.涉及的基础知识我们先梳理下上面所涉及的一些......
  • 高效遍历:C++中分隔字符串单词的3种方法详解与实例
     概述:在C++中,遍历由空格分隔的字符串的单词有多种方法,包括使用`std::istringstream`、手动遍历字符和正则表达式。其中,`std::istringstream`是简单高效的选择,通过流提取单词。手动遍历字符较为繁琐,正则表达式方法更灵活但可能有性能开销。根据实际需求选择方法,本文提供了清晰......
  • C语言编程规范——注释
    一、注释简介一般情况下,源程序有效注释量必须在20%以上。注释的目的是解释代码的目的、功能和采用的方法,提供代码以外的信息,帮助读者理解代码,防止没必要的重复注释信息。二、注释类型1.单行注释将注释放在双斜杠//后面,从双斜杠到行尾都属于注释。#include<stdio.h>intmain......
  • golang初学:交叉编译
    goversiongo1.22.1windows/amd64Windows11+amd64x86_64x86_64GNU/Linux--- 序章golang支持跨平台,支持的方式是在一个平台编译其它平台的可执行程序。本文介绍Windows11(开发主机)上编译Linux(目标主机)上的可执行程序。 #gobuild 开发主机和目标......
  • c语言实现vector及其相关函数(自存)
    #include<stdio.h>#include<stdlib.h>#definePREALLOC_MAX1024#defineDEFAULT_CAPACITY8typedefintE;typedefstruct{E*elements;//指向堆空间的数组intsize;//元素的个数intcapacity;//数组的容量}Vector;voidpush_back(Vect......
  • 04. C语言数据使用方式
    【C语言简介】计算机的运行由CPU指令控制,为了让计算机执行指定功能,需要将这些功能对应的指令数据集中存储在一起,制作为一个计算机文件,这个文件称为程序,CPU通过读取程序中的指令确定要执行的功能,制作程序时无需直接编写指令数据和数学数据,这些数据使用代码表示,从而方便记忆和编写,......
  • Redis持久化、主从与哨兵架构详解
    参考图灵课堂https://zhuanlan.zhihu.com/p/443951927https://blog.csdn.net/weixin_37548768/article/details/124538778?spm=1001.2014.3001.5502https://www.runoob.com/redis/redis-transactions.html   redis支持持久化到磁盘,这样可用进一步保证数据的完整性。re......