目录
一、常用命令
1、简单编译
2、多个程序文件的编译
3、检错
4、库文件连接
二、GCC编译
1、准备工作
2、编译过程
3、汇编
4、链接
三、分析ELF文件
1、ELF文件的段
2、反汇编ELF
四、总结
一、常用命令
1、简单编译
(1)创建文件,输入如下代码,并且编译
#include<stdio.h>
int main(void)
{printf("Hello World!\n");return 0;
}
步骤:
(2)预处理
(3)编译使之成为汇编代码
预处理后,对生成的test.i文件编译,生成汇编代码
(4)汇编
对生成的汇编代码文件test.s,将其编译为目标文件
(5)连接
将程序的目标文件与所需的所有附加目标文件连接起来(包括静态连接库和动态连接库),生成可执行文件
(6)执行
2、多个程序文件的编译
3、检错
(1)按照ANSI/ISO C语言标准进行编译器诊断
(2)在所有产生警告的地方停止编译,要求修改
(3)
4、库文件连接
(1)编译成可执行文件
进行编译test.c为目标文件
(2)链接
把所有目标文件链接成可执行文件
(3)强制链接时使用静态链接库
二、GCC编译
1、准备工作
创建工作目录test0,然后用gedit文本编辑器生成一个.c文件
源代码:
#include <stdio.h>
//此程序很简单,仅仅打印一个 Hello World 的字符串。
int main(void)
{
printf("Hello World! \n");
return 0;
}
2、编译过程
(1)预处理
将.c文件预处理生成.i文件
hello.i文件可作为普通文本文件打开查看
(2)编译
将预处理生成的hello.i文件编译生成汇编程序hello.s
hello.s文件中为汇编代码
3、汇编
将编译生成的hello.s文件汇编生成目标文件hello.o
4、链接
先进行连接,使用gcc hello.c-o hello会进行动态库进行连接
使用size查看大小
用ldd命令查看一个可执行程序依赖的共享库
可以看出可执行文件连接了很多动态库
使用命令 gcc -static hello.c -o hello 会进行静态库链接
使用size命令查看ELF文件的大小
用ldd命令查看一个可执行程序依赖的共享库
可以看出text的尺寸变大且没有链接动态库
三、分析ELF文件
链接后生成的文件为ELF格式的可执行文件,一个ELF文件通常被链接为不同的段,常见的段譬如.text、.data、.rodata、.bss 等段
1、ELF文件的段
ELF 文件格式如下图所示,位于 ELF Header 和 Section Header Table 之间的都 是段(Section)。一个典型的 ELF 文件包含下面几个段:
.text:已编译程序的指令代码段。
.rodata:ro 代表 read only,即只读数据(譬如常数 const)。
.data:已初始化的 C 程序全局变量和静态局部变量。
.bss:未初始化的 C 程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试
使用 readelf -S查看各个section的信息:
2、反汇编ELF
ELF文件无法被当做普通文本文件打开,需要使用反汇编的方法查看一个ELF文件包含的指令和数据。
使用 objdump -D 对其进行反汇编如下:
objdump -D hell
使用 objdump -S 将其反汇编并且将其 C 语言源代码混合显示:
$ gcc -o hello -g hello.c //要加上-g 选项
$ objdump -S
四、总结
在完成这次的练习中,我了解学习了有关GCC的常用命令,熟练了如何去进行预处理、编译、汇编、链接的相关操作,并且理解了有关静态库链接、动态库链接的概念和ELF文件的结构与查看方式,对于我学习Linlinux有很大的帮助。