相关概念
编译器
- 变量“代表”数据,函数名“代表”函数,两者需放到内存中才能被CPU使用。
- 内存中所有信息以二进制形式存储,而CPU靠地址来访问内存。
- 在程序代码中用变量名来指代变量,而变量在内存中是根据地址来存放的,二者之间的映射通过编译器完成。编译时根据目标运行平台来安排程序中的地址,如加载到内存中的地址、代码段入口地址等。编译器将程序中所有变量名转成该变量在内存中的存储地址。
寄存器
- CPU内部以寄存器来锁存数据。因此,寄存器本质上也是存储器的一种,但位于CPU内部,故CPU访问寄存器比访问内存的速度更快。寄存器中所有数据只是临时存储,之后就被送到别处。
- 计算机系统32位 / 64位取决于寄存器数据的最大存储长度。
总线
- 分类:地址总线、数据总线、控制总线。
- 地址总线的宽度决定了CPU的寻址能力,即CPU能达到的最大地址范围。
编译过程
- .c—(预处理)–>.i—(编译)–>.s—(汇编)–>.o—(连接)—>可行性文件。可执行文件存在硬盘中是静态文件,称之为程序。
- 当程序被启动时,操作系统进行以下操作:
1、将程序的代码段和数据段从硬盘复制到内存中(XIP例外);
2、创建PCB(进程控制块),描述程序的各种信息;
3、在代码段中定位入口函数的地址,CPU从此开始执行。
- 源程序 → 词法分析器 → 语法分析器 → 中间代码生成器 → 代码优化器 → 代码生成器 → 目标程序,期间有符号表管理器和错误处理器的参与。
编译得到的obj文件是0/1类型的机器码,即CPU能够识别的微指令,不能直接执行,调用的函数代码并不在obj文件中,要通过链接得到exe文件
词法分析
将源程序根据C语言的词法规则切割成分立的token(标识符、数字、符号)并鉴别属性。
int a = 10;
//int、a、=、10、;
语法分析
从连续的token中识别出标识符、关键字、数字、运算符,并存储为token流(符号流),从中识别出符合C语言语法的语句。
int a = 10;
//返回值类型 变量名 运算符 变量值 ;
token流与C语言规定的规则相符,编译器就认定为变量赋值语句,以语法树的形式在内存中记录下来。
语义分析
检测源程序中的语义错误并收集代码生成阶段要用到的类型信息,还要进行符号表的管理。
从语法树到中间代码
- 由于计算机存在多种架构的CPU硬件,如X86、ARM平台。考虑到程序在不同CPU之间的可移植性,先转换成一个通用的、抽象的CPU指令代码。然后,根据具体的CPU指令集落实到具体的CPU目标代码,这就是中间代码的设计思想。
- 之后,中间代码转换为目标代码——汇编代码,由汇编器依照选定系统的目标文件,将汇编文件转为具体的目标文件,此时已经是CPU的机器指令。
- 最后,连接器将目标文件链接成选定系统的可执行文件。
格式文件
.bin文件
最纯粹的二进制机器代码,内部没有地址标记,是直接的内存映象表示,可以在裸机上运行,文件大小即文件所包含的数据的实际大小。
.hex文件
- 常用来保存单片机或其他处理器的目标程序代码,保存物理程序存储去中的目标代码映象。是机器代码的十六进制形式,用一定文件格式的ASCII码来表示。
- hex文件由记录组成,每一行代表一个记录。每条记录都由一个冒号“:”打头,其格式: :BBAAAATTHHHH…HHHHCC
– BB:字节个数。
– AAAA:数据记录的开始地址,高位在前,低位在后。
– TT:Type
---- 00数据记录,用来记录数据。
---- 01记录结束,放在文件末尾,用来标识文件结束。
---- 02用来标识扩展段地址的记录
---- 04扩展地址记录(表示32位地址的前缀)
– HHHH:一个字(Word)的数据记录,高字节在前,低字节在后。TT之后共有BB/2个字的数据。
– CC:占据一个Byte的CheckSum。
.elf文件
- x86 Linux系统下的一种常用目标文件格式,有3种主要类型:
1、适于连接的可重定位文件(relocatablefile),可与其它目标文件一起创建可执行文件和共享目标文件。*.o文件就是可重定位文件,由 *.c源文件经过预编译、编译、汇编步骤生成;
2、适于执行的可执行文件(executablefile),用于提供程序的进程映像,加载到内存执行。LinuxOS下,通常 gcc -o test test.c,生成的test文件就是ELF格式的,在LinuxShell下输入./test就可以执行。Windows下的.exe;
3、共享目标文件(sharedobjectfile),连接器可将它与其它可重定位文件和共享目标文件连接成其它的目标文件,动态连接器又可将它与可执行文件和其它共享目标文件结合起来创建一个进程映像。简单的例子,就是.lib文件。
.axf文件
和elf文件类似,但axf是arm开发的armcc编译器生成的。gcc编译器生成的一般称为elf,两者很像,但是格式上有区别。
.map文件
映射文件,展示映射项目构建的链接阶段的细节。通常包含程序的全局符号、交叉引用和内存映射等等信息。目前,大多数编译套件(主要是其中的链接器)都可以生成map文件。常见的GCC、VC、IAR都可以输出map文件(PC(x86)平台的map文件与ARM平台的差别较大)。
特性
可移植性,C/C++,系统硬件资源的接口,如进程调度、网络通信等,这些是每个操作系统独有的(主要还是学习标准C)
跨平台,java/python,无需修改就可以在任何平台运行