gcc hello.c 的背后是什么

在c语言中编写“hello world!” 程序基本成了每个学习过c语言的人必写的程序之一,点击运行,(如果没错的话)就会在黑框里面显示 hello world!

在LInux 下使用 gcc 来编写 "hello world!" 程序时,也是只用到最简单的命令(假设 hello world! 程序的原文件名为 hello.c ):

[……]$gcc hello.c

[……]$./a.out

其实,在 gcc 的背后,编译器为你做了四个步骤: 分别是 预编译、编译、汇编、链接。

【1】预编译:

预编译是预编译器cpp把源代码文件和相关的头文件 (如 stdio.h ) 预编译成一个 .i 文件,

预编译的过程相当于如下命令:

$gcc -E hello.c -o hello.i    或者   $gcc hello.c > hello.i

预编译的处理规则:

(1) 将所有的 "#define" 删除,并展开所有的宏定义;

(2)处理所有的条件预编译指令,比如:" #if    #ifdef   #elif   #else    #endif ";

(3)处理所有的 "#include" 预编译指令

(4)删除所有的注释 "//" 、 "/* */";

(5)添加行号和文件名标识,以便编译时产生的行号信息以及用于编译错误或警告时能够显示行号;

(6)保留所有的 "#pragma" 编译器指令

【2】编译:

编译过程是编译器gcc把预处理完的文件进行词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件。编译过程是最复杂的过程之一。

编译过程可以使用如下命令:

$gcc -S hello.i -o hello.s    或者  $gcc -S hello.c -o hello.s

都可以得到汇编输出文件 hello.s

【3】汇编:

汇编是汇编器as把汇编代码转变成中间目标文件。

汇编过程可以使用如下命令:

$gcc -c hello.s -o hello.o   或者   $gcc -c hello.c -o hello.o

可以得到中间目标文件 hello.o

【4】链接:

链接是链接器ld把中间目标文件和相应的库一起链接成为可执行文件。

如果前面使用的是$gcc hello.c 命令,默认会产生一个 a.out 的可执行文件, 使用命令 $./a.out执行该可执行文件

如果前面使用的是$gcc -o test hello.c 命令,会产生一个test 的可执行文件,使用命令$./test执行该文件

上述两种方法效果是一样的。

gcc编译过程图解:

           

时间: 2024-08-01 22:47:21

gcc hello.c 的背后是什么的相关文章

gcc -static hello.c 背后究竟发生了什么

大家可能经常使用gcc -static ***.c,那么这个静态链接究竟使用了什么命令,又链接了哪些库呢? 我们首先来分析libc.a是个什么文件.我们已经知道了xxx.so是动态链接库,xxx.o是静态链接库或者说可重定位文件,/bin/bash为可执行文件. libc.a其实是很多可重定位文件的集合,而且每个可重定位文件中一般都只写一个函数.例如printf.o只有printf一个函数,目的是为了在静态链接时少链接一些没用的库. 首先使用命令locate libc.a,我们会找到libc.a

words2

餐具:coffee pot 咖啡壶coffee cup 咖啡杯paper towel 纸巾napkin 餐巾table cloth 桌布tea -pot 茶壶tea set 茶具tea tray 茶盘caddy 茶罐dish 碟plate 盘saucer 小碟子rice bowl 饭碗chopsticks 筷子soup spoon 汤匙knife 餐刀cup 杯子glass 玻璃杯mug 马克杯picnic lunch 便当fruit plate 水果盘toothpick 牙签中餐:bear's

C程序运行的背后(1)

一个成功的男人背后,至少有一个伟大的女人:一个不成功的男人,至少有一双手. 而一个C程序,无论成功不成功,它的背后一定有一个操作系统,一个shell,一套工具链. 世界本就不公平.隐藏在显而易见的事实背后的,你若能看透,便可以站在对自己公平的那一端. 1.进程地址空间 一个进程一旦建立,就会自认为占有4G内存(X86_32),这个内存被称作虚拟内存,也就是进程的地址空间.在Linux下,进程地址空间的布局大致如下图所示,其中的用户空间大致由这些部分组成: 代码段 初始化数据段 未初始化数据段 堆

gcc编译过程简述

在linux系统上,从源文件到目标文件的转化是由编译器完成的.以hello.c程序的编译为例,如下: [email protected]: gcc -o hello hello.c 在这里,gcc编译器读取源文件hello.c,并把它翻译成一个可执行文件 hello. 这个翻译过程可分为四个阶段逐步完成:预处理,编译,汇编,链接,如下图所示. 逐步做下简单分析: 在未编译前,hello.c 的源代码如下 #include <stdio.h> int main() { printf("

Mac OS X 背后的故事

Mac OS X 背后的故事 作者: 王越  来源: <程序员>  发布时间: 2013-01-22 10:55  阅读: 25840 次  推荐: 49   原文链接   [收藏] 作者王越,美国宾夕法尼亚大学计算机系研究生,中国著名 TeX 开发者,非著名 OpenFOAM 开发者. Mac OS X 背后的故事(一)力挽狂澜的Ellen Hancock Mac OS X 背后的故事(二)Linus Torvalds的短视 Mac OS X 背后的故事(三)Mach之父Avie Tevan

Objective C block背后的黑魔法

前言 block在Objective C开发中应用非常广泛,我们知道block会捕获外部对象,也知道使用block要防止循环引用. "知其然而不知其所以然"是一件很痛苦的事情,那么block这套机制在OC中是如何实现的呢?本文通过从C/C++到汇编层面分析block的实现原理. Clang clang是XCode的编译器前端,编译器前端负责语法分析,语义分析,生成中间代码(intermediate representation ). 比如当你在XCode中进行build一个.m文件的时

c 各种编译器(gcc clang)

很多时候,出现一些类似GNU,GCC,CLANG,LLVM等与编译器有关的名词的时候,都不太清楚它到底是干嘛的,理解这些东西后, 对于xcode中很多配置型的需求修改起来都会得心应手,因此有必要了解透彻他们直接的关系与区别. 1 GUN “GNU,名称来自Gnu's Not Unix"的缩写,一个类UNIX的操作系统,由GNU计划推动,目标在于创建一个完全兼容于UNIX的自由软件环境.” 由于当时UNIX系统是商业软件,是收费的,而且有一部分源码是没有开放的,所以在1983年,理查德·斯托曼提出

goroutine背后的系统知识

Go语言从诞生到普及已经三年了,先行者大都是Web开发的背景,也有了一些普及型的书籍,可系统开发背景的人在学习这些书籍的时候,总有语焉不详的感觉,网上也有若干流传甚广的文章,可其中或多或少总有些与事实不符的技术描述.希望这篇文章能为比较缺少系统编程背景的Web开发人员介绍一下goroutine背后的系统知识. 1. 操作系统与运行库2. 并发与并行 (Concurrency and Parallelism)3. 线程的调度4. 并发编程框架5. goroutine 1. 操作系统与运行库 对于普

开源软件之七宗罪以及背后的阴谋

开源软件之七宗罪以及背后的阴谋 jopen 2012-10-29 11:31:22 ? 发布 摘要:我们每天使用着大量的开源软件,我们歌颂她赞美她.当有人站出来说一句开源不好 肯定会激起N多人站出来批评.然后给你列举出N多开源的好处和闭源的坏处. 我们每天使用着大量的开源软件,我们歌颂她赞美她.当有人站出来说一句开源不好 肯定会激起N多人站出来批评.然后给你列举出N多开源的好处和闭源的坏处. 首先我不反对开源,本文只是无聊时候的自己一点思考.想喷的各位请看完再喷.谢谢 自从开源运动发起以后.各种