• [go]go如何把代码运行起来的?


    参考

    代码在硬盘上是一堆二进制

    • 弄清楚文件在硬盘/内存中的存储值
    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("hello world")
    }
    

    vim查看 :%!xxd

    在终端里执行 man ascii

    观察发现, 中间列和最右列 是一一对应的。
    也就是说,刚刚写完的 hello.go 文件都是由 ASCII 字符表示的(文本文件)

    • 汇编转换位机器指令

    • go语句转换为机器指令过程

    Go 程序并不能直接运行,每条 Go 语句必须转化为一系列的低级机器语言指令,将这些指令打包到一起,
    并以二进制磁盘文件的形式存储起来,也就是可执行目标文件。

    探索编译和运行的过程

    通常将编译和链接合并到一起的过程称为构建(Build)。

    编译过程就是对源文件进行词法分析、语法分析、语义分析、优化,最后生成汇编代码文件,以 .s 作为文件后缀的汇编指令。
    
    汇编器会将汇编代码转变成机器可以执行的指令。
    由于每一条汇编语句几乎都与一条机器指令相对应,所以只是一个简单的一一对应,比较简单,没有语法、语义分析,也没有优化这些步骤。
    
    • 编译器的作用: 将高级语言翻译成机器语言

    6个阶段

    • 词法分析

    使用一种有限状态机的算法

    有限自动机是有限个状态的自动机器。
    我们可以拿抽水马桶举例,它分为两个状态:“注水”和“水满”。
    摁下冲马桶的按钮,它转到“注水”的状态,而浮球上升到一定高度,就会把注水阀门关闭,它转到“水满”状态。
    

    我们会识别出if、else、int这样的关键字,main、printf、age这样的标识符,+、-、=这样的操作符号,还有花括号、圆括号、分号这样的符号,以及数字字面量、字符串字面量等。这些都是Token。

    token一般分为这几类:关键字、标识符、字面量(包含数字、字符串)、特殊符号(如加号、等号)。

    slice[i] = i * (2 + 6)
    

    总共包含 16 个非空字符,经过扫描(对那棵树 递归下降算法(Recursive Descent Parsing)构建一棵完整的树)后,

    - src/cmd/compile/internal/syntax/scanner.go
    最关键的函数就是 next 函数,它不断地读取下一个字符(go utf8以字符为单位)
    func (s *scanner) next() {
    
    
    - src/cmd/compile/internal/syntax/token.go
    
    var tokstrings = [...]string{
        // source control
        _EOF: "EOF",
    
        // names and literals
        _Name:    "name",
        _Literal: "literal",
    
        // operators and operations
        _Operator: "op",
        _AssignOp: "op=",
        _IncOp:    "opop",
        _Assign:   "=",
        _Define:   ":=",
        _Arrow:    "<-",
        _Star:     "*",
    
        // delimitors
        _Lparen:    "(",
        _Lbrack:    "[",
        _Lbrace:    "{",
        _Rparen:    ")",
        _Rbrack:    "]",
        _Rbrace:    "}",
        _Comma:     ",",
        _Semi:      ";",
        _Colon:     ":",
        _Dot:       ".",
        _DotDotDot: "...",
    
        // keywords
        _Break:       "break",
        _Case:        "case",
        _Chan:        "chan",
        _Const:       "const",
        _Continue:    "continue",
        _Default:     "default",
        _Defer:       "defer",
        _Else:        "else",
        _Fallthrough: "fallthrough",
        _For:         "for",
        _Func:        "func",
        _Go:          "go",
        _Goto:        "goto",
        _If:          "if",
        _Import:      "import",
        _Interface:   "interface",
        _Map:         "map",
        _Package:     "package",
        _Range:       "range",
        _Return:      "return",
        _Select:      "select",
        _Struct:      "struct",
        _Switch:      "switch",
        _Type:        "type",
        _Var:         "var",
    }
    
    
    • 语法分析
      例如“2+3*5”,你会得到一棵类似下图的AST。

    • 语义分析

    以“You can never drink too much water.” 这句话为例。它的确切含义是什么?
    是“你不能喝太多水”,
    还是“你喝多少水都不嫌多”?

    实际上,这两种解释都是可以的,我们只有联系上下文才能知道它的准确含义。

    词法分析是把程序分割成一个个Token的过程,可以通过构造有限自动机来实现。
    
    语法分析是把程序的结构识别出来,并形成一棵便于由计算机处理的抽象语法树。可以用递归下降的算法来实现。
    
    语义分析是消除语义模糊,生成一些属性信息,让计算机能够依据这些信息生成目标代码。
    
    • 目标代码生成与优化
      不同机器的机器字长、寄存器等等都不一样,意味着在不同机器上跑的机器码是不一样的。最后一步的目的就是要生成能在不同 CPU 架构上运行的代码。
      为了榨干机器的每一滴油水,目标代码优化器会对一些指令进行优化,例如使用移位指令代替乘法指令等。

    • 链接
      链接过程就是要把编译器生成的一个个目标文件链接成可执行文件。最终得到的文件是分成各种段的,比如数据段、代码段、BSS段等等,运行时会被装载到内存中。各个段具有不同的读写、执行属性,保护了程序的安全运行。

    从上图: 将编写的一个c程序(源代码 )转换成可以在硬件上运行的程序(可执行代码 ),需要进行
        编译阶段
            先通过“编译器 “把一个 .c/.cpp 源代码 编译成 .s的汇编代码;
            再经过“汇编器 ” 把这 个.s的汇编代码汇编成 .o 的 目标代码
        链接阶段
            通过连接其他 .o 代码(如果需要的话) 库文件 和 1 中的.o 目标代码生成可执行文件
    
    该文件流被这三种程序(红色)的加工,分别表现出四种形式(蓝色),这就是c程序的编译和链接过程。
    
    如果再详细的话,编译器在将源文件编译成汇编文件的过程又分为:预处理阶段(生成 .i 代码) 和  优化阶段
    

    go编译流程查看

  • 相关阅读:
    ReentrantLock 非公平锁不公平在哪
    spring 初始化Bean
    spring 循环引用问题,在一次问题调试过程中发现有个小伙伴竟然把循环引用设置成false了。估计是百度的时候没小心额外的代码吧。。。
    Maya2019下载安装与激活
    Maya2014下载安装与激活
    Maya2017下载安装与激活
    Windows 好用的护眼软件
    万兴全能格式转换器_11.2.0.232 下载安装和激活
    处理视频相关的软件
    几款好用的录屏软件推荐
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/12179867.html
Copyright © 2020-2023  润新知