0x02 LiteOS内核详解--浅谈程序编译

举报
樊心昊 发表于 2020/05/25 13:18:33 2020/05/25
【摘要】 摘要:编译一个程序时,看似点击IDE中的build按钮或者输入一句gcc xx.c -o xx就完成了编译,其实这中间发生了很多有趣的步骤,下面我们以GCC工具链为例,让我带着大家一起来看看吧,这样有助于后面理解LiteOS中的中断接管机制以及driver层设备注册等等。 一个xxx.c文件编译为xxx.hex/.bin文件经历了哪些步骤? 预处理下图是hello.c文件内容,打印A的值,A...

摘要:编译一个程序时,看似点击IDE中的build按钮或者输入一句gcc xx.c -o xx就完成了编译,其实这中间发生了很多有趣的步骤,下面我们以GCC工具链为例,让我带着大家一起来看看吧,这样有助于后面理解LiteOS中的中断接管机制以及driver层设备注册等等。

 

一个xxx.c文件编译为xxx.hex/.bin文件经历了哪些步骤?

image.png

 

预处理

下图是hello.c文件内容,打印A的值,A变量定义在A.h文件中

image.png

下图是A.h文件内容:

image.png

我现在使用如下命令gcc -E hello.c -o hello.E,让hello.c文件只预处理,得到hello.E文件,其中已经用在A.h文件中的“int A = 18;”语句对hello.c文件中的#include ”A.h”进行了替换,如图:image.png

编译

编译的本质就是将C语言代码翻译为汇编代码,gcc -S hello.c -o hello.S

Hello.S文件的部分内容:

image.png

 

汇编

汇编就是将汇编代码转换为机器码的过程:gcc -c hello.S -o hello.o,因为机器码文件里面全部都是由0\1二进制组成,所以我们无法直接看懂,我这里使用nm hello.o查看其中的符号:

image.png

上面的”00000000000”是指这些符号所处的地址,因为没有链接所以地址为0,D是指在该符号定义在的初始化数据段,U是指该符号没有在该文件中定义,需要等链接的时候去其他文件中寻找,T是指该符号位于代码区。

链接

链接就是将Hello.c文件中用到的外部函数和其本身的函数根据链接脚本(这里用的是默认链接脚本,例如LiteOS中的链接脚本是os.ld)的要求链接到一起,生成可执行文件,我这里使用gcc hello.o -o hello,链接生成可执行文件hello,我们用到了printf库函数,链接器就会去库中帮我们寻找prinf函数并链接在一起。

执行./hello,就可以得到如下打印:image.png

用nm查看hello可执行程序,这次就能得到所有数据和函数的地址了:

image.png

 

 


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。