C&CPP代码编译链接运行过程简单描述

编译

一个工程的所有源文件(*.c *.cpp *.cc *.h *.hpp)是独立编译的
1.预处理(预编译):以#号开头的预处理指令,如#include #defifine #ifdef #else #elif #endif 除
#progma(链接so库,需要保留到链接阶段),删除注释等
2.编译阶段:语法,语义分析检查,代码优化(gcc -O2),汇总所有的符号(函数符号,变量的符号)这个过程即为通过词法分析和语法分析,在确认所有的指令都符合语法规则之后,将其翻译成等价的中间代码表示或汇编代码. 这里进行汇编的过程是通过编译器进行执行的, 在编译(Compiler)的作用下经过预处理器输入的程序就编译成了汇编代码.

3.汇编阶段:汇编的过程实际上就是将汇编代码翻译成目标机器语言的过程.,生生成的目标文件也就是与源程序在逻辑上等效的机器语言代码. 生成的机器语言代码被称为目标代码, 生成的二进制文件被称为目标文件, 也成为二进制文件
一般的生成文件的数据类型为:

  • 符号起始区块(BSS Block Started by Symbol的缩写)
  • 正文段(text segment 或译作代码段)//主要存放程序的指令, 可读可执行不可写
  • 数据段(data segment)//主要存放全局变量和静态数据. 可读可写可执行

链接:

将一个或多个由编译器或汇编器生成的目标文件外加库链接为一个可执行文件连接方式有静态链接和动态连接

C&CPP代码编译链接运行过程简单描述_第1张图片
过程如下:
1.合并所有obj文件+*.a(静态库)的各个段,包括text,data,bss。。。其中符号表合并开始做符号解析(所有对符号的引用,都要在其它obj文件中找到该符号的定义),符号解析完成,给所有符号分配虚拟地址
2.符号的重定向(因为符号都有虚拟地址了,然后去text代码段,把所有符号的地址更新成符号的正确地址就可以了)
3.生成依赖于本地平台的可执行文件(.exe[PE格式] (windows) a.out[ELF格式](linux))

运行:

1.只把可执行文件的text、rodata、data、bss映射到虚拟地址空间上(实际上未分配过任何物理内存)
2.在文件头中,读取程序的入口地址(main函数的入口地址),放入CPU的PC寄存器当中
3.开始运行,执行指令或者访问数据(需要在内存上按地址访问一条指令或者一个数据)。CPU发出的是虚拟地址,要经过MMU做地址映射操作(页目录页表映射),因为没有分配过物理页面,所以肯定会发生缺页异常,转入linux内存的缺页异常处理程序do_page_fault进行异常处理,分配响应的物理页面,把物理页面的信息写入响应的页表项当中,然后重启地址映射过程,肯定能够映射成功,然后访问物理内存上存储的指令或者数据。

你可能感兴趣的:(C++)