您的位置:首页 > 数据 >
从源代码到二进制行程序 C语言的编译过程是怎样的?
来源:CSDN 2023-01-12 08:17:18

前言

C语言程序从源代码到二进制行程序都经历了那些过程?本文以Linux下C语言的编译过程为例,讲解C语言程序的编译过程。

编写hello world C程序:


(相关资料图)

// hello.c#includeint main(){    printf("hello world!\n");}

编译过程只需:

$ gcc hello.c # 编译$ ./a.out # 执行hello world!

这个过程如此熟悉,以至于大家觉得编译事件很简单的事。事实真的如此吗?我们来细看一下C语言的编译过程到底是怎样的。

上述gcc命令其实依次执行了四步操作:1.预处理(Preprocessing), 2.编译(Compilation), 3.汇编(Assemble), 4.链接(Linking)。

示例

为了下面步骤讲解的方便,我们需要一个稍微复杂一点的例子。假设我们自己定义了一个头文件mymath.h,实现一些自己的数学函数,并把具体实现放在mymath.c当中。然后写一个test.c程序使用这些函数。程序目录结构如下:

├── test.c└── inc    ├── mymath.h    └── mymath.c

程序代码如下:

// test.c#include#include "mymath.h"// 自定义头文件int main(){    int a = 2;    int b = 3;    int sum = add(a, b);     printf("a=%d, b=%d, a+b=%d\n", a, b, sum);}

头文件定义:

// mymath.h#ifndef MYMATH_H#define MYMATH_Hint add(int a, int b);int sum(int a, int b);#endif

头文件实现:

// mymath.cint add(int a, int b){    return a+b;}int sub(int a, int b){    return a-b;}

1.预处理(Preprocessing)

预处理用于将所有的#include头文件以及宏定义替换成其真正的内容,预处理之后得到的仍然是文本文件,但文件体积会大很多。gcc的预处理是预处理器cpp来完成的,你可以通过如下命令对test.c进行预处理:

gcc -E -I./inc test.c -o test.i

或者直接调用cpp命令

$ cpp test.c -I./inc -o test.i

上述命令中-E是让编译器在预处理之后就退出,不进行后续编译过程;-I指定头文件目录,这里指定的是我们自定义的头文件目录;-o指定输出文件名。

经过预处理之后代码体积会大很多:

X文件名文件大小代码行数

预处理前test.c146B9

预处理后test.i17691B857

预处理之后的程序还是文本,可以用文本编辑器打开。

2.编译(Compilation)

这里的编译不是指程序从源文件到二进制程序的全部过程,而是指将经过预处理之后的程序转换成特定汇编代码(assembly code)的过程。编译的指定如下:

$ gcc -S -I./inc test.c -o test.s

上述命令中-S让编译器在编译之后停止,不进行后续过程。编译过程完成后,将生成程序的汇编代码test.s,这也是文本文件,内容如下:

// test.c汇编之后的结果test.s    .file   "test.c"    .section    .rodata.LC0:    .string "a=%d, b=%d, a+b=%d\n"    .text    .globl  main    .type   main, @functionmain:.LFB0:    .cfi_startproc    pushl   %ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp    .cfi_def_cfa_register 5    andl    $-16, %esp    subl    $32, %esp    movl    $2, 20(%esp)    movl    $3, 24(%esp)    movl    24(%esp), %eax    movl    %eax, 4(%esp)    movl    20(%esp), %eax    movl    %eax, (%esp)    call    add     movl    %eax, 28(%esp)    movl    28(%esp), %eax    movl    %eax, 12(%esp)    movl    24(%esp), %eax    movl    %eax, 8(%esp)    movl    20(%esp), %eax    movl    %eax, 4(%esp)    movl    $.LC0, (%esp)    call    printf    leave    .cfi_restore 5    .cfi_def_cfa 4, 4    ret     .cfi_endproc.LFE0:    .size   main, .-main    .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"    .section    .note.GNU-stack,"",@progbits

请不要问我上述代码是什么意思!-_-

3.汇编(Assemble)

汇编过程将上一步的汇编代码转换成机器码(machine code),这一步产生的文件叫做目标文件,是二进制格式。gcc汇编过程通过as命令完成:

$ as test.s -o test.o

等价于:

gcc -c test.s -o test.o

这一步会为每一个源文件产生一个目标文件。因此mymath.c也需要产生一个mymath.o文件

4.链接(Linking)

链接过程将多个目标文以及所需的库文件(.so等)链接成最终的可执行文件(executable file)。

命令大致如下:

$ ld -o test.out test.o inc/mymath.o ...libraries...

结语

经过以上分析,我们发现编译过程并不像想象的那么简单,而是要经过预处理、编译、汇编、链接。尽管我们平时使用gcc命令的时候没有关心中间结果,但每次程序的编译都少不了这几个步骤。也不用为上述繁琐过程而烦恼,因为你仍然可以:

$ gcc hello.c # 编译$ ./a.out # 执行

关键词:
相关文章
环球观速讯丨解读 | 《矿山救护队标准化定级管理办法》

环球观速讯丨解读 | 《矿山救护队标准化定级管

  近日,应急管理部印发了《矿山救护队标准化定级管理办法》(以下简称《定级办法》)。为落实好《定级办法》,现解读如下:  一、制定背更多

2023-01-11 10:07:48
暖冬天气抑制需求 美国煤炭价格上周暴跌45%|最新资讯

暖冬天气抑制需求 美国煤炭价格上周暴跌45%|最新

  美国煤炭价格从历史高点大幅下跌,原因是暖冬天气缓解了对化石燃料需求。数据显示,截至1月6日当周,北部阿巴拉契亚地区的煤炭价格跌至每更多

2023-01-11 10:08:57
环球快报:2023年能源经济走势向好

环球快报:2023年能源经济走势向好

  1月8日,2023年能源经济预测与展望研究系列报告发布。报告显示,2022年中国能源经济稳步回升,2023年能源经济走势向好。  最新发布的《更多

2023-01-11 09:57:50
煤矿智能化进入快速发展阶段_百事通

煤矿智能化进入快速发展阶段_百事通

  日前召开的全国矿山智能化建设和安全发展推进视频会透露,2020年八部委联合印发《关于加快煤矿智能化发展的指导意见》和全国煤矿智能化建更多

2023-01-11 10:12:06
山东能源集团党委书记、董事长李伟当选“2022中国经济年度人物

山东能源集团党委书记、董事长李伟当选“2022中国

  1月6日,2022中国十大经济年度人物颁奖盛典在北京举行。中国梦杯•中国经济新闻人物——2022十大经济年度人物评选是由中国经济传媒协会主更多

2023-01-10 11:15:29
2022年黄骅港完成煤炭运量20515.8万吨 世界热点

2022年黄骅港完成煤炭运量20515.8万吨 世界热点

1月8日,船舶在黄骅港码头装运煤炭。黄骅港煤炭堆场转运设备在作业(1月8日摄,无人机照片)。  位于河北沧州的黄骅港是西煤东运、北煤南运更多

2023-01-10 10:12:46
世界热议:2022年煤矿智能化重大进展发布会在京召开

世界热议:2022年煤矿智能化重大进展发布会在京召开

  1月7日,2022年煤矿智能化重大进展发布会在京召开。本次发布会旨在展示交流2022年煤矿智能化科技创新和建设成果,总结推广经验,发挥先进更多

2023-01-10 10:16:42
环球热头条丨2023年内蒙古煤炭目标产量将达到12.5亿吨

环球热头条丨2023年内蒙古煤炭目标产量将达到12.5

  记者从1月5日召开的2023年全区能源工作会议上获悉,2023年,我区将继续肩负起保障国家能源安全的重大政治责任,全力以赴保障能源安全稳定更多

2023-01-10 10:00:38
2022年我国原煤产量过亿吨企业增至7家

2022年我国原煤产量过亿吨企业增至7家

  据中国煤炭工业协会统计与信息部初步统计,2022年,全国原煤产量超5000万吨企业15家,与去年持平。产量合计约为259亿吨,较去年增加约13亿更多

2023-01-10 09:55:09
每日热闻!CCTD重磅分析:2023年煤炭市场展望

每日热闻!CCTD重磅分析:2023年煤炭市场展望

  2022年,虽然受到国际能源市场持续紧张、高温干旱暴雨极端天气、疫情扰动以及输入性通胀等因素影响,但是在政策调控和市场机制的配合下,更多

2023-01-10 10:15:31