嵌入式系统作业gcc编译器背后的故事

目录

一、gcc编译器是什么

二、gcc有什么用

三、实际操作

1.编写hello world代码

2.编程过程

 (1)预处理

 (2)编译

(3)汇编 

 (4)链接

3.分析ELF文件 

(1)ELF文件的组成:

(2)反汇编ELF

四 、结论

五、参考文献


一、gcc编译器是什么

1.官方定义:GCC(GNU Compiler Collection,GNU编译器套件)是由GNU开发的编程语言编译器。GNU编译器套件包括C、C++、 Objective-C、 Fortran、Java、Ada和Go语言前端,也包括了这些语言的库(如libstdc++,libgcj等。)GCC的初衷是为GNU操作系统专门编写的一款编译器。GNU系统是彻底的自由软件。此处,“自由”的含义是它尊重用户的自由.

二、gcc有什么用

GCC是编译工具(编辑器),能将C语言编写的程序转换为处理器能处理的二进制代码。Binutils:二进制程序处理工具,包括:ar、as、size、ldd等。
(1)as:主用于汇编。
(2)ld:主用于链接。
(3)ar:主用于创建静态库:
若将多个.o目标文件生成一个库文件,则需要静态库和动态库(共享库)。
windows系统下:静态库是.lib为后缀的文件,动态库是.dll为后缀的文件; linux系统下:静态库是.a为后缀的文件,动态库是.so为后缀的文件。
静态库和动态库区别在于代码被载入的时间不同:静态库的代码在编译过程中已被载入可执行程序,所以体积较大。动态库的代码在可执行程序运行时被载入内存,简单引用,体积较小。
linux系统下,可用ldd命令查看可执行程序的共享库。
多个程序同时运行时 ,且包含动态库,则动态库更节省内存。
(4)ldd:可查看可执行程序的动态库。
(5)size:列出可执行文件每个部分的尺寸和总尺寸,代码段、数据段和总大小等。
(6)objdump:反汇编。
(7)readelf:显示有关ELF文件的信息。


三、实际操作

1.编写hello world代码

#include<stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}

2.编程过程

 (1)预处理

使用gcc进行预处理

gcc -E hello.c -o hello.i

//将源文件hello.c文件预处理生成hello.i文件

//gcc 的选项-E使gcc在进行完预处理后即停止

 (2)编译

使用gcc编译命令如下:

gcc -S hello.i -o hello.s

//将预处理生成的hello.i文件编译生成hello.s文件

//gcc的选项-s使gcc在执行完编译后停止,生成汇编程序

(3)汇编 

使用gcc汇编命令如下:

gcc -c hello.s -o hello.o
//将编译生成的hello.s文件汇编生成目标文件hello.o
//gcc的选项-c使gcc在执行完汇编后停止,生成目标文件

//或直接调用as进行汇编
 as -c hello.s -o hello.o
//使用as将hello.s文件汇编生成目标文件

 (4)链接

1、链接也分为动态链接和静态链接:
(1)静态链接:程序在编译阶段直接把静态库加入到可执行文件中去,这样的可执行文件会比较大。

(2)动态链接:程序执行时再从系统中将相应的动态库加入到内存中去。Linux系统中,gcc编译链接时动态库搜索路径的顺序通常为:
1从gcc命令参数-L指定路径寻找;
2再从环境变量LIBRARY_PATH指定的路径寻址;
3再从默认路径/lib、/usr/lib、/usr/local/lib寻找。

Linux系统中,执行二进制文件时的动态库搜索路径的顺序通常为:
1先搜索编译目标代码时指定的动态库搜索路径;
2再从环境变量LD_LIBRARY_PATH指定的路径寻址;
3再从配置文件/etc/ld.so,sonf中指定的动态库搜索路径;
4再从默认路径/lib、/usr/lib寻找。

在Linux系统下,可用ldd命令查看一个可执行程序依赖的动态库。

2、若命令“gcc hello.c -o hello动态库进行链接,生成ELF可执行文件的大小(用size命令查看)和链接的动态库(用ldd命令查看),示例如下:

gcc hello.c -o hello

size hello

ldd hello

 3、若使用命令“gcc -static hello.c -o hello”则会使用静态库进行链接,生成ELF可执行文件的大小(用size命令查看)和链接的动态库(用ldd命令查看),示例如下:

gcc -static hello.c -o hello

size hello//可见text的代码尺寸极大

ldd hello//说明没有动态链接库

3.分析ELF文件 

(1)ELF文件的组成:

ELF文件由4部分组成,分别是ELF头(ELF header)、程序头表(Program header table)、节(Section)和节头表(Section header table)。

一个典型的ELF文件包含下面几个段:

.text:已编译程序的指令代码段。
.rodata:ro表示read only,即只读数据。
.data:已初始化的C程序全局变量和静态局部变量。
.bss:未初始化的C程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试。

可以使用readelf -S查看其各个section的信息如下:

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

四 、结论

GNUC编译器 即gcc是一个功能强大的ANSI C兼容编译器,会操作其他操作系统下的一种C编译器,就能很快掌握GCC.

五、参考文献

gcc编译器背后的故事

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值