索引
前言
在STM32等Cortex-M内核的MCU学习开中,常用的IDE——Keil5
中使用的是ARMCC
,也是一个C语言编译器。GCC
,GNU Compiler Collection
,同ARMCC
是差不多的一个东西,但是GCC
是自由免费的。
程序编译过程
gcc
编译程序很简单,执行gcc -o helloworld helloworld.c
就可以直接编译生成可执行文件helloworld
,这个过程也屏蔽了很多步骤,整个编译过程做了一下工作。
1、预处理
主要是处理C程序中带"#"的语句,像#include
、#define
、#if
等等这些预处理指令。它们不是C程序本身的组成部分,但却是必不可少的一部分,有这些预处理语言写起程序菜更方便。预处理后将程序处理为后缀命为.i
的文件。
获得预处理文件:
gcc -o -E helloworld.i helloworld.c
2、编译
预处理阶段生成的.i文件还不能给程序运行,所以代码还要继续处理,到这个阶段就是编译,将.i文件
的代码编译处理成汇编文件(.s)
。GCC
生成的就是x86架构
的汇编文件。GCC for ARM
生成的是ARM架构的汇编文件。不同平台的汇编指令集不一样,所以相应的平台使用相应的GCC
。
获得汇编文件:
gcc -o helloworld.s helloworld.i -S
3、汇编
汇编文件的指令是和处理器指令 一一对应的,这个阶段,汇编器会将汇编文件翻译成可重定位的elf格式可重定位程序文件,即.o文件
可重定位文件:
程序已经包含了能让处理器运行的指令,但是程序中的全局符号(函数和变量
)位置还没确定。哔哩哔哩这么多,简单地说可重定位文件就是就是函数和变量入口地址还没确定的文件。没确定那肯定就不能运行。
获得elf可重定位文件:
gcc -o helloworld.o helloworld.s -c
4、链接
如上所说,经过汇编的文件还不能运行。还需要最后这一步:链接
,将所有.o文件
链接成可执行程序。
链接的作用:
- 重定位
- 合并相同权限的段
elf可重定位的程序文件中是按照段(section)
存放程序的,如存放运行的代码.text
段、存放初始化了的全局变量、静态局部变量的.data
段,未初始化的全局变量、静态局部变量的.bss段
等。
执行readelf helloworld.o -S
查看程序段分布。
GCC常用编译选项
-o
输出指定文件名
- gcc -o helloworld helloworld.c
-E
输出预处理后的代码文件
- gcc -o helloworld.i helloworld.c -E
-S
输出编译生成的汇编文件
- gcc -o helloworld.s helloworld.c -S
-c
输出链接后的可重定位文件
- gcc -o helloworld.o helloworld.c -c
-I
指定头文件路径
- gcc -o helloworld helloworld.c -I<include_path>
-g
编译结果中加入调试信息
- gcc -o helloworld helloworld.c -g
-L
制定库文件路径
- gcc -o helloworld helloworld.c -L<lib_path>
-O
制定代码优化等级,等级越高优化程度越高
- -O0
- -O1
- -O2
- -O3
-static
编译时使用静态链接库文件
- gcc -o helloworld helloworld.c -<lib_name> -static
-Wall
输出警告信息
- gcc -o helloworld helloworld.c -Wall