一、GCC编译器的使用
1.创建一个hello.c
hello.c
#include <stdio.h> int main(void) { printf("Hello World! \n"); return 0; }
2.程序的编译过程
上述编译过程是分为四个阶段进行的,即预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)。
预编译(将源文件 hello.c 文件预处理生成 hello.i)
gcc -E hello.c -o hello.i
编译(将预处理生成的 hello.i 文件编译生成汇编程序 hello.s)
gcc -S hello.i -o hello.s
汇编(将编译生成的 hello.s 文件汇编生成目标文件 hello.o)
gcc -c hello.s -o hello.o # 用gcc进行汇编 as -c hello.s -o hello.o # 用as进行汇编
链接(分为静态链接和动态链接,生成可执行文件)
gcc hello.c -o hello # 动态链接 gcc -static hello.c -o hello # 静态链接
执行
用 size 查看文件大小,ldd链接了那些动态库
3.多个程序文件的编译
通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用 GCC 能够很好地管理这些编译单元。假设有一个由 test1.c 和 test2.c 两个源文件组成的程序,为了对它们进行编译,并最终生成可执行程序 test,可以使用下面这条命令
gcc test1.c test2.c -o test
检错
gcc -pedantic illcode.c -o illcode
链接
把所有目标文件链接成可执行文件
gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test
二、GCC编译器背后的故事
1.准备代码
hello.c
#include <stdio.h> int main(void) { printf("Hello World! \n"); return 0; }
2.编译过程
预处理 使用 gcc 进行预处理
gcc -E hello.c -o hello.i #-E 使 GCC 在进行完预处理后即停止
编译 使用 gcc 进行编译的命令如下
gcc -S hello.i -o hello.s #-S 使 GCC 在执行完编译后停止,生成汇编程序
汇编 使用 gcc 进行汇编的命令如下
gcc -c hello.s -o hello.o #-c 使 GCC 在执行完汇编后停止,生成目标文件
链接
gcc hello.c -o hello
三、分析ELF文件
1.ELF文件的段
readelf -S hello #查看各个段的信息
2.反汇编ELF
由于 ELF 文件无法被当做普通文本文件打开,如果希望直接查看一个 ELF 文件包 含的指令和数据,需要使用反汇编的方法。 使用 objdump -D 对其进行反汇编
objdump -D hello
部分展示
使用objdump -S 将其反汇编并且将其C语言源代码混合显示出来
gcc -o hello -g hello.c //要加上-g选项 objdump -S hello