编译连接运行原理(将.cpp文件编译为exe文件的过程):编译运行原理是指将C/C++语言通过汇编生成汇编语言并转换为机器语言的过程。
编译运行原理之C++篇
一、预编译(生成*.i文件)
1.将所有的“#define”删除,并且展开所有的宏
2.处理掉所有的条件预编译指令,如:"#if","#ifend","#endif","#elif","else","#endif"
3.处理"#include"指令,这是一个递归的过程
4.删除所有的注释"//",和"/**/"
5.添加行号和文件名标识
6.保留所有的#pragma编译器指令,待编译器使用
二、编译(生成*.s文件,处理局部符号)
1.词法分析
2.语法分析
3.语义分析
4.代码优化(阐述优缺点:优点:提高效率 缺点:不可控(多线程下))
5.生成汇编指令
三、汇编(*.o 文件,也叫目标文件)
翻译指令 汇编器是将汇编代码转换为机器可以执行的命令,每一个汇编语句几乎都对应一条机器指令
注:汇编遗留的问题:
1.强弱符号的处理
2.符号表(什么是符号表?符号表在编译程序过程中需要不断收集、记录和使用源程序中一些语法符号的类型和特征相关信息,这些信息一般以表格存储于系统中,如常数表,变量名表,过程名表,标号表等,统称为符号表,对于符号表组织、构造和管理方法的好坏会直接有影响到编译系统的运行效率)
3.指令段外部符号的地址不确定
四、链接(生成.exe文件,也叫做可执行文件或者可重入的二进制文件)
1.合并段和符号表
2.符号解析(在每个文件符号(引用外部符号)的地方找到符号的定义)
3.分配地址和空间
4.符号的重定位(对.o文件中.text段指令的无效地址给出具体的虚拟地址或相对位移量)
五、运行(.exe 程序——>进程)
1.建立虚拟地址空间和物理内存的映射(创建内核映射结构体)分配页表和页目录
2.加载指令和数据段
3.入口地址写入下一行指令寄存器
编译运行原理之linux篇
一、预编译(mian.c):gcc main.c -E -o main.i
1.宏替换
2.处理预编译指令
3.删除注释
4.处理#include
二、编译(main.i):gcc -S main.i -o main.s
1.词法分析
2.语法分析
3.语句分析
4.代码优化
5.符号汇总
6.汇总符号
7.处理函数和数据
三、汇编(main.s):gcc -c main.s -o main.o
1.将汇编指令翻译成二进制
2.生成各符号表
3.生成各个段section
四、连接(main.o):gcc main.o -o a
1.合并各个section,调整段大小以及段起始位置,合并符号表,进行符号解析(符号解析只会解析GLOBAL符号,LOCAL符号并不会解析)
2.符号重定位
五、运行(a.out/exe)