全球快报:从源代码到二进制行程序 C语言的编译过程是怎样的?
前言
【资料图】
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 # 执行
标签:
相关推荐:
最新新闻:
- 肥东一中2021高考成绩查询 肥东一中隆重举行2021届高考励志报告会
- word2010的分节符及分页符在哪里?分节符以及分页符位置介绍
- 自定义控件GDI绘制在主程序报错System怎么解决?_热门看点
- 【并行开发】mpjdaemon批处理命令中的问题分析_世界快资讯
- 怎么安装directx 11.1?设置安装directx 11.1步骤
- 今日起 Win7/Win8.1彻底与大家说再见了|全球快资讯
- 我的文档位置在哪?我的文档被删除了怎么恢复?
- 风力发电机原理是什么?风力发电机原理详解
- 实时:Unity显示印度语异常 如何纠正错误的印度文?
- Trojan.Win32怎么彻底删除?Trojan.Win32清除方法步骤
- reactnative开发环境安装androidstudio 安装问题如下:环球微动态
- ADSL是什么?使用ADSL宽带上网的方法及说明
- QQExternal.exe是什么进程?QQExternal.exe进程删除步骤
- windows防火墙打不开怎么办?windows防火墙打不开是怎么回事?
- 谷歌搜索打不开如何处理?三种谷歌搜索打不开的解决方法
- 笔记本液晶屏维修方法是什么?液晶屏的软排线撕坏了怎么办?
- 怎么激活office2015?永久激活Office2015的方法
- 笔记本键盘出现错乱怎么办?电脑键盘错乱完美解决-全球快讯
- kingsoft是什么文件夹?kingsoft删除影响wps使用吗?
- 磁碟机病毒是什么?电脑磁碟机病毒要如何查杀?
- 全球快报:从源代码到二进制行程序 C语言的编译过程是怎样的?
- dnf按键连发怎么设置?红眼x连发如何设置几秒合适?
- Protel99SE怎么使用?Protel99SE的基本教程详细步骤
- 缓存文件是什么 缓存文件删了有什么影响?
- qq垃圾文件怎样请理?qqprotect.exe进程怎样结束?
- 揭秘720°三维全景3D实景地图制作技术 浅谈三维全景3D实景地图核心技术:世界快资讯
- 如何设置Windows7Computer?Windows7Computers配置指南:今日关注
- NppTools.dll是什么文件?NppTools.dll文件丢失了怎么办?
- 一文读懂Mapduce框架Map:类MapReduce框架实现1.0和改进版本
- 如何解决Windows Installer错误?InstMsiW.exe安装及常见问题解答
- 回顾老罗的经典语录:彪悍的人生不需要解释!
- Oracleclient是什么?关于Oracleclient的环境变量设置笔记分析
- cscript.exe是什么?cscript.exe自动启动解决方法
- 环球百事通!推荐10个渐变色网站 设计师的色彩网站推荐
- 今亮点!国内外格斗机器人大比拼 谁才是真正的王者?
- unity中的反射:用程序集元数据:当前播报
- 世界观察:高中数学第五章线性规划方法 单纯形表法的计算步骤
- 《F1车队经理2022》销量超60万 但仍低于预期
- 《战神5》交互设计师加盟《神奇女侠》游戏团队
- 北回归线能扛起旅游复苏的大旗吗?
- 《英雄连3》最终技术测试本周开启 全员皆可参与:新动态
- 韩国游客称在日本遭芥末袭击 怀疑厨师故意为之
- 代购“印度神药”,骗子比药还多 每日聚焦
- 年货节白菜价秒杀: 2TB固态硬盘仅需599元
- 环球速讯:苹果或于6月前发布AR/VR头戴产品 号称取代iPhone
- AMD锐龙7000智酷版上架:6核仅需1549元_天天新动态
- 【速看料】恐怖压抑!《中国奇谭》"鹅鹅鹅"导演早期作品曝光
- 环球关注:摩根大通:做空太疯狂,我们将步入科技股主导的逼空
- 劳斯莱斯销量爆棚,创119年历史最高销售记录_焦点报道
- “妖镍”之后又有新冲击?“镍王”青山据称增产
- 《森林之子》AI更加智能 可协助战斗、建造等_世界视讯
- 每日热议!《魔咒之地》公布“电影级”预告 视听级享受
- 预购《死亡空间:重制版》可免费获《死亡空间2》
- Xbox开发者直面会1/25举行 介绍多款作品信息_环球热点
- 道指盘初涨110点,纳指和热门中概领跑,但B站跌近5%
- 暴雪将推出“电子骨灰盒” 《魔兽世界》国服即将关停 环球热消息
- 突发 讴歌正式退出中国市场
- 钛金属加持依然直角边框 iPhone 15 Ultra渲染图曝光 世界独家
- 标致推出未来EV概念车Inception-环球微资讯
- AMD锐龙7000新U型号看不懂:编号更高 但是频率更低 天天消息
- 分析师:PS5不缺货是《最终幻想16》成功的关键-全球速讯
- 天天日报丨千亿景林高云程“内部信”曝光:股市将迎“双击之年”,未来有三大机会和六类“生意群”
- 世界热文:趁着股价强势反弹,一波港美股公司启动股权融资!
- 当前关注:百年历史中最大亏损!瑞士央行去年亏了1430亿美元
- 三星Galaxy Z Flip4:用立式自由拍摄秀出聚会中不一样的精彩
- PlayStation推广自家截图功能:别用门锁拍照了!
- 国产PC掌机OnexPlayer2超多使用场景:比NS还丰富!-当前热点
- 我们变老了!2023年很多大作将迎来自己的10岁生日:世界观察
- 摩根士丹利“大空头”:美股低估了衰退风险,可能再跌22%|全球简讯
- 进展迅速!曝暴雪国服代理谈判进入"二选一"阶段 当前快讯
- 消息!元宇宙里的资本家,已经开始靠剥削小孩赚钱了
- Xbox官网发布2023年登陆XGP的游戏 超50款-世界微资讯
- 如果日本央行结束负利率 日元未来怎么走?-快讯
- 优酷过冬,禁止“白嫖”:环球消息
- 豆瓣评分高达9.5!《中国奇谭》"林林"专属壁纸公布-当前滚动