gcc编译C语言文件过程

本文详细介绍了GCC编译器如何将C源代码编译成可执行程序的过程,包括一次性编译、分两步编译以及针对pwn的四步编译。内容涵盖预处理、编译、汇编和链接四个阶段,解析了每个阶段的功能和输出文件,帮助读者深入理解GCC的编译机制。
摘要由CSDN通过智能技术生成

一.一次性编译

1、新建、编辑源文件

  • 首先,建个名为“测试”的文件夹,cd进入文件夹
  • 接下来用touch在文件夹内创建一个空白的 hello.c 源文件。(hello.c 其实就是一个纯文本文件,并没有任何特殊格式)
  • 再用gedit编辑源文件

2、生成可执行程序

$ cd 测试       #进入源文件所在的目录

$ gcc hello.c  #在gcc命令后面紧跟源文件名

这样的话就会在文件夹中生成一个a.out的可执行程序,这就是最终生成的可执行文件。

*Linux不以文件后缀来区分可执行文件,Linux下的可执行文件后缀理论上可以是任意的,这里的.out只是用来表明它是 GCC 的输出文件。不管源文件的名字是什么,GCC 生成的可执行文件的默认名字始终是a.out

通过-o可以自定义执行文件名称,也可以将文件输入到其他目录中(其他目录必须存在)

gcc hello.c -o a/hello.out

3、运行可执行程序

./a.out

表示运行当前目录下a.out程序

*如果不写./,Linux会到系统路径下查找 a.out,而系统路径下不存在这个程序,所以会运行失败

运行结果如下:
在这里插入图片描述

4.总结

$ cd 测试 #进入源文件所在目录(cd)

$ touch hello.c #新建源文件(touch)

$ gedit hello.c #编辑源文件(gedit)

$ gcc hello.c #生成可执行程序

$ ./a.out #运行可执行程序

二.分两步编译

1.编译

利用-c将源文件(hello.c)编译为目标文件(hello.o)

gcc -c hello.c

在这里插入图片描述

2.链接

在gcc命令后紧跟目标文件的名字,就可以将目标文件(.o)链接成可执行文件(.out)

gcc hello.o

3.总结

$ cd 测试 #进入源文件所在目录(cd)

$ gcc -c hello.c #编译源文件为目标文件(-c)

$ gcc hello.o #链接目标文件为可执行文件(紧跟)

$ ./a.out #运行可执行程序

三.pwn所需的分四步编译

首先如果我们在编译时添加-save temps和- -verbose编译选项,那么我们就可以保存下来编译的中间文件。
在这里插入图片描述
由此可以看到,GCC的编译过程主要分四部分

1.预处理

这个阶段输入.c源文件,主要处理文件中的带“#”的语句,将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些代码输出到一个“.i”文件中等待进一步处理。在命令选项中添加编译选项-E可以单独执行预处理:

$ gcc -E hello.c -o hello.i

hello.i的部分内容
在这里插入图片描述
预处理的一些处理规则:

1.递归处理“#include”预处理命令,将对应文件的内容复制到指定的位置;

2.删除所有“#define”指令,并且在其引用的位置递归展开所有的宏定义

3.处理所有条件预处理指令:“#if”,”#ifdef”,“#elif”,”#else”,”#endif”等;

4.删除所有注释

5.添加行号和文件名标识

2.编译

这个阶段输入第一阶段生成的 .i 文件,输出成汇编语言 .s 文件

gcc -S hello.i -o hello.s
gcc -S hello.i -o hello.s -masm=intel -fno-asynchronous-unwind-tables

//-masm=intel可以将汇编文件制定成Intel模式,
//-fno-asynchronous-unwind-tables则可以生成没有的cfi宏的汇编指令,以提高可读性

hello.s汇编文件的内容
![在这里插入图片描述](https://img-blog.csdnimg.cn/2648472edb7c4a5f8bf5dcf222d05b14.pn在汇编代码中函数printf()被换成了puts()函数,是因为在有单一参数的时候,两者十分类似,而GCC 的优化策略就进行了替换以提高性能

3.汇编阶段

这个阶段输入第二阶段的汇编文件 .s 文件,然后编译成机器语言 .o 文件,在Linux系统上一般表现为ELF目标文件(OBJ文件):

gcc -c hello.s -o hello.o
gcc -c hello.c -o hello.o
//操作对象也可以是.c,直接生成目标文件

此时的hello.o是一个可重定位文件,可使用objdump命令打开,即:

objdump -sd hello.o -M intel
//利用此命令可以打开hello.o目标文件

在这里插入图片描述

4.链接

gcc hello.o –o hello -static

从而得到hello文件,通过./hello从而运行该程序

如果我们通过上述objdump命令的话,可以得到一个静态连接的可执行文件,即:

objdump -sd hello -M intel

其中包含大量的库,以下只是部分:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值