go 语言hello world 的编译过程

作者简介:C/C++ 、Golang 领域耕耘者,创作者
个人主页:作者主页
如果感觉博主的文章还不错的话,还请关注➕ 、点赞👍 、收藏🧡三连支持一下博主哦~

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语言的底层是如何做的。在分析源码过程中也是可以应用这个原理的。

如果觉得对你有帮助的话:
👍 点赞,你的认可是我创作的动力!
🧡 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值