栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

go 语言hello world 的编译过程

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

go 语言hello world 的编译过程

文章目录
    • 1. 比较各种语言
      • 1.1 c/c++
      • 1.2 java
      • 1.3 js
      • 1.4 go
    • 2. go 中的runtime
      • 2.1 位置
      • 2.2 区别
      • 2.3 runtime 特点
      • 2.4 runtime 能力
      • 2.4 runtime other能力
    • 3. hello world 编译过程
      • 3.1 编译code步骤分析
      • 3.2 编译code过程原理
      • 3.3 词法分析
      • 3.4 句法分析
      • 3.5 语义分析
      • 3.6 中间码(SSA)
      • 3.7 机器码生成
      • 3.8 链接
      • 3.9 编译过程总结

1. 比较各种语言

1.1 c/c++
  1. c语言不是面向对象
  2. 直接编译为机器码,不需要执行环境
  3. 一次编码只能使用一种平台 (涉及到系统函数相关时)
  4. 自己处理GC问题, 容易内存泄漏
1.2 java
  1. 编译为中间码(字节码)
  2. 需要特定执行环境(JVM)
  3. 一次编译多出执行
  4. 有虚拟化损失(因为不是直接编译成的机器码)
1.3 js
  1. 不需要编译,直接解释执行
  2. 需要执行环境(浏览器)
  3. 有虚拟化损失
1.4 go
  1. 直接编译为二进制,没有虚拟化损失
  2. 自带运行环境,无需处理GC处理(后面有讲)
  3. 一次编码可以使用多种平台(后面讲)
  4. 超强的并发支持能力与并发易用性(容易上手,一般的程序员就可胜任)
2. go 中的runtime 2.1 位置

在官方包中(external libraries),里面有一个runtime文件夹

2.2 区别

runtime就是支撑程序运行时的组件,也称作程序运行环境,很多的语言都有runtime

  1. java : java 虚拟机
  2. js : 浏览器内核
2.3 runtime 特点
  1. go 没有虚拟机的概念
  2. runtime 作为程序的一部分打包进二进制产物 (是谷歌程序员开发go 的写的支撑包,是代码,与用户程序一起编译)
  3. runtime 随用户程序一起运行
  4. runtime 与用户程序没有明显界限,直接通过函数调用 (跟java不同,java 是通过字节码支持的)
2.4 runtime 能力
  1. 内存管理能力
  2. 垃圾回收能力(GC)(java 就是jvm, c++就是手动)
  3. 超强的并发能力(协程调度)
2.4 runtime other能力
  1. 有一定的屏蔽系统调用能力 (c/c++不跨平台就是因为不同系统的api 不同,在不同平台就需要处理不同的系统调用,无法屏蔽系统调用能力)
  2. 一些go 的关键字其实是runtime 下的函数
3. hello world 编译过程 3.1 编译code步骤分析
package main

import "fmt"

func main() {
	fmt.Println("Hello world!")
}

这里用go build -n 一下,代表不实际编译它,只是输出编译过程

看下面一张图可以发现runtime 永远跟着用户程序一起编译的,所以有这个runtime.a

最后通过这个link 成一个exe 执行文件

3.2 编译code过程原理


前面都是编译成一堆.a 文件,最后链接成可执行文件

3.3 词法分析

将源代码翻译成token,token 是代码中最小语义结构

3.4 句法分析

token 序列经过处理,变成语法树

简单可以这样理解

3.5 语义分析
  1. 类型检查
  2. 类型推断
  3. 查看类型是否匹配
  4. 函数调用内联(优化部分代码)
  5. 逃逸分析(后续深入)
3.6 中间码(SSA)

go语言内部为了处理不同平台的差异,先生成中间代码(SSA)


查看从代码到SSA中间码的整个过程
$env:GOSSAFUNC=“main”
export GOSSAFUNC="main" 添加上去就行
输出某个函数的SSA代码
接下来可以专门看SSA 中间码(这个和汇编还是有点区别的)

通过看SSA 可以很清楚的知道调用了什么函数

3.7 机器码生成
  1. 先生成Plan9汇编代码(windows 平台和linux 平台的Plan9汇编是不一样的)
  2. 最后编译为机器码
  3. 输出的机器码为.a 文件

查看Plan9 汇编代码方法, 输入go build -gcflags -S main.go, 之后可以看到这么一串汇编代码
这样可分分析机器在那几行代码中做了什么

3.8 链接

将各个包进行链接,包括runtime

3.9 编译过程总结

我们也将词法分析—句法分析—语义分析 叫做编译前端;中间码生成—代码优化—机器码生成 叫做 编译后端

当然咯,了解此过程并不是我们需要去更改go 的编译过程(大佬清随意),而是有时在遇到问题后,可以通过命令看中间码或者Plan9汇编代码看看go语言的底层是如何做的。在分析源码过程中也是可以应用这个原理的。

参考:
后台服务器:https://course.0voice.com/v1/course/intro?courseId=5&agentId=0

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/928099.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号