目录
一、GCC编译器的使用
1、创建一个 hello.c
mkdir test0
cd test0
vim hello.c
hello.c 内容如下:
#include <stdio.h>
int main(void)
{
printf("Hello World! \n");
return 0;
}
2、程序的编译过程
这个程序,一步到位的编译指令是:
gcc hello.c -o test
实质上,上述编译过程是分为四个阶段进行的,即预处理(也称预编译,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.准备
创建test0,使用vim编写hello.c
mkdir test0
cd test0
编写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
部分展示:
四、汇编代码“hello.asm”编译生成可执行程序
在ubuntu中下载安装nasm,对示例汇编代码“hello.asm”编译生成可执行程序,并与上述用C代码的编译生成的可执行程序大小进行对比
1.nasm的安装
2.创建一个"hello.asm"文件
touch hello.asm
gedit hello.asm
3.编译、链接和运行
nasm -f elf64 hello.asm //编译
ld -s -o hello hello.o //链接
./hello //输出