编译器

编译器是把代码编译成机器能够执行的二进制机器码的工具,对于嵌入式设备基本都是须要使用交叉编译工具链。java

编译好以后的程序,才能够在目标设备上面运行。linux

编译器通常分为以下步骤工具

预编译 —> 编译 —> 连接优化

 

拿linux gcc编译器来讲ui

预编译

预编译是解析提供的的程序源码的头文件,而且对于其中的宏进行展开。spa

对于一套源码咱们每每会定义不少宏,以下.net

#define            定义一个预处理宏
#undef            取消宏的定义

#if                   编译预处理中的条件命令,至关于C语法中的if语句
#ifdef              判断某个宏是否被定义,若已定义,执行随后的语句
#ifndef            与#ifdef相反,判断某个宏是否未被定义
#elif                若#if, #ifdef, #ifndef或前面的#elif条件不知足,则执行#elif以后的语句,至关于C语法中的else-if
#else              与#if, #ifdef, #ifndef对应, 若这些条件不知足,则执行#else以后的语句,至关于C语法中的else
#endif             #if, #ifdef, #ifndef这些条件命令的结束标志.
defined          与#if, #elif配合使用,判断某个宏是否被定义
blog

编译器经过解析这些字段能够为后续的编译提供统一的输入环境。文档

预编译以后的hello_wrold.c 以下图编译器

编译

 编译,顾名思义就是把咱们人能看懂的代码编译成咱们看不懂的二进制代码。

编译器优化:编译时会读取某些关键字,对于有这些关键字修饰的变量会不作优化处理,好比volunteer 。

CPU指令集(二进制)—> 汇编 —>C语言 —>java    (计算机语言的发展)

因为计算机只能执行二进制码,因此任何语言都是须要经过编译以后才能在上面执行的。(解析器是另一套东西,后面能够汇总一下解析器的原理)

gcc编译器能够把所提供的代码编译成汇编语言,汇编语言里各类寄存器的操做移位等。

 

连接

gcc编译其中有静态编译和动态编译的区别,静态编译会把对应库文件里的代码也拷贝到当前的程序上。

而动态编译则只是把当前的代码编译成二进制码,与所须要的动态模块进行连接。

在运行动态编译的二进制程序时,程序会到系统库亦或者连接库里找对应标记的代码段来运行,静态编译则不须要。

动态编译的优势是节省了空间,并且CPU又是串行的,毕竟像printf这样的代码段谁须要谁加载,用完释放,其乐融融。

给系统动态库添加其余的目录  export LD_LIBRARY_PATH=/opt/au1200_rm/build_tools/bin: $LD_LIBRARY_PATH:

 

 

相关指令

gcc -E xx.c -O xx.i    #预编译

gcc -S xx.i -o xx.s    #编译成汇编

gcc -C xx.s xx.o     #编译成二进制

objdump –d xx.o     #反汇编

gcc xx.o -o xx.exe    #连接

 

参考文档:https://blog.csdn.net/feng_ge3/article/details/80721059

多谢