C++开始前篇,深入编译链接

   C++开始,为什么要写这个东西,因为按照课堂进度的话,现在的C++已经学到模板以及重载了,有时却仍然因为一些小问题无法解答,原因是忘记了开始时学到的知识,深知不能像猴子掰棒子一样,掰一个扔一个,因此,现在踏踏实实的回顾一下。另外希望各位博友们随时指正,不甚感激!

  前部分大概分为,1,深入编译链接。2,函数调用堆栈。3,C跟C++的区别。4,面向对象思想。。。(未完待续)

  温故而知新。  

-------------------------------------------------------------------------------------------------------------------------------------

  一,深入编译链接。

  通过c语言的学习,我们知道,代码要想成为可执行文件,要经过,预处理->编译->汇编->链接->可执行文件。当然,c++也是如此,但是现在需要更加细化一点。(详细介绍编译与链接环节)

  以。main.cpp为例

  1,预处理/预编译(不做语法检查)  main.c->main.i

  2,编译(语法检查)         main.i->mian.s       
    1),在编译过程中,不分配内存(填数据的地址都是0地址)
    2),代码优化,汇总所有的符号。    
   过程:
 源代码程序->记号(扫描器)->语法树(语法分析器)->有类型标示的语法树(语义分析器)->中间代码(源代码优化器)->目标代码(代码生成器与代码优化器)
   1,首先源代码程序被输入到扫描器(Scanner),进行词法分析:运用一种类似与有限状态机的算法将源代码的字符序列分割成一系列的记号。
   2,语法分析器将对词法分析产生的记号进行语法分析。整个分析过程采用上下文无关语法。(上下文无关语法,指语法中重写规则的形式)语法分析之后产生语法树。
   3,语义分析,由语义分析器来完成,语义分析之后,整个语法树表达式都被标示了类型。,如果有些类型需要做隐式转换,语义分析器会在语法树中插入相应的转换节点。
   4,源代码优化,将有类型标示的语法树先转化为中间代码,然后由源代码优化器优化掉简单的表达式,比如array[index]=(index + 4)*(2+6). “2+6”会直接被优化掉。
   5,目标代码生成与优化,代码生成器将中间代码转换成目标机器代码。然后由目标代码优化器后产生目标代码。
  3,汇编                
     根据平台将汇编指令转换成机器码
  4,链接(包括地址和空间的分配,符号决议和重定位等)
    1),合并所有obj文件的段,并调整段偏移和段长度,合并符号表进行“符号解析”,此时分配内存地址!   
    2),对所有global符号进行处理,对local符号不进行处理。
    关于“符号解析”,所有obj符号表中对符号引用的地方都要找到该符号定义的地方。
 
    链接的核心:符号的重定位。
    关于符号的重定位,通俗的说,就是地址修正的过程。比如:在代码中,有个全局变量var,它在目标文件A中,但是我们要在目标文件B里面访问这个全局变量,B中若有指令,movl   $0x2a,var   此指令的功能是给这个var赋值0x2a。编译目标文件B,得到这条指令  的         机器码,C705     00 00 00 00  2a 00 00 00 
       (mov指令码)      (目标地址)  (源常量)
    由于在编译目标文件B的时候,编译器并不知道变量var的目标地址,所以在编译器无法确定地址的情况下,将其目标地址置为0。假设A  和B链接后,变量var的地址确定下来是0x1000,那么链接器将会把这个指令的目标地址部分修改为0x1000。
  

    

原文地址:https://www.cnblogs.com/junlinfeizixiao/p/6046301.html