C++ 学习笔记 六 (C++文件运行过程分析)
学习了“程序员的自我修养—链接、装载与库”后,写点自己对C++运行过程的理解(抄袭、借鉴),图引用自 “程序员的自我修养—链接、装载与库” 一书
C++文本文件(.c,.h)需要经过预处理(.i)、编译(.s)、汇编(.o)、链接(.exe)、装载后才能在内存中运行。
预处理:
1.递归导入#include头文件进行替换 2.处理宏 3.去除注释 4.添加行号和文件名标识,方便debug
编译:
1.词法分析 扫描所有文本文件,将字符串划分为Token(关键字、标识符、字面量),其中标识符(我们所命名的)存入符号表、字面量存入文字表(忘记啥表名了。。) 2.语法分析 将每一条语句转化成一个语法树,语句就是表达式(复杂语句是简单表达式的组合),计算机对于中序表达式很难处理,所以生成树再转成后序方便处理 3.语义分析 判断语句语义是否合法,如指针不能做乘除运算、 处理过后,语法树上加上了数据类型 一些隐式类型转换也是在这 4.优化 一些常量表达式的计算、一些操作顺序变化等 5.目标码 这里我觉得就是后序表达式的处理(其实没细看)
汇编:
汇编语言转化成机器指令
链接:
其实编译后的文件已经是可执行文件了,只是如果引用了其他动态库,则需要将它们的指令也带上,而各自的目标文件指令都是以相对地址表示的,所以需要做一个偏移,转化成内存里的绝对地址.
装载:
将可执行文件按页划分,部分加载进内存,通过页面置换来完整执行。
内存模型:
最高位1G是内核空间,从0xcfffffff往下是栈(可变),0x4000000之上是动态链接库,下面是堆空间(向上可变),再下面是数据区(全局变量/静态变量 .data是初始化的, .bss是未初始化的),代码区(机器指令、类相关信息、全局函数、类成员函数.text、常量.rodata,初始化函数.init)。