编译过程
预处理
宏展开,略
编译
词法分析,语法分析,语义分析,中间代码生成,
目标代码生成
这一步是将中间代码编程汇编代码,这个过程中会把符号换成地址,如果是外部的符号,则留下符号作为占位符,等以后再链接修改
汇编
把汇编码转为机器指令
静态链接
有个重定位关系
ELF结构
首先讲一下我们的程序,这里讲elf结构
Elf文件格式可以有:
- 已初始化全局变量和静态变量data,
- 未初始化全局变量bss,
- 只读数据/编译器常量rodata,
- 机器码text等Section。
- 符号表,重定位信息等略
另外全局变量可能在数据段或者bss
static静态变量,如果修饰局部变量,和全局变量放在同一个区域,可以把它看成是作用域为那个局部的全局变量,同理类成员
未初始化区域bss为什么要和全局变量分开来装,猜也猜得到因为省空间
字符串常量,字面值都是放在rodata,比如cpp的虚表就是放在这里的,运行时期修改会有segmentation fault
程序加载运行时,.rodata段和.text段通常合并到一个Segment中,操作系统将这个Segment的页面只读保护起来,防止意外的改写。这一点从readelf的输出也可以看出来
启动过程
整个装载的过程
首先操作系统会读取可执行文件的头部,检查文件的合法性,然后从头部中的“Program Header”(这个program header是什么)中读取每个“Segment”的虚拟地址、文件地址和属性(这里说的segment是内存五区之类的吧),并将它们映射到进程虚拟空间的相应位置,接着操作