深入理解 Golang: Go 程序的编译运行过程

news2024/12/29 8:58:51

Go program 编译过程

package main

import "fmt"

func main() {
 fmt.Println("Hello Go")
}

编译前端

  1. 词法分析
    • 将源代码翻译成 Token(最小语义结构)
  2. 句法分析
    • Token 序列经过处理,变成语法树 AST
  3. 语义分析
    • 类型检查
    • 类型推断
    • 函数调用内联
    • 逃逸分析

编译后端

  1. 中间代码生成(SSA)
    • 处理不同平台的差异,生成中间代码
  2. 代码优化
  3. 机器码生成
    • 生成 Plan9 汇编代码
  4. 链接
    • 将各个包(.a 文件)进行链接,包括 runtime

查看从代码到 SSA 中间码的过程

# windows
$env:GOSSAFUNC="main"
# linux
export GOSSAFUNC="main"

执行 go build main.go,得到 ssa.html 文件。
在这里插入图片描述
在这里插入图片描述
从 sourses -> ast -> … -> genssa

查看 Plan9 汇编代码

go build -gcflags -S main.go

在这里插入图片描述

Go program 的入口

tips: 第一行代码并非为用户自定义的 main 方法

  1. 首先进入 %GOROOT%\src\runtime 下的对应的 rt0_xxx.s 汇编文件,如在 windows 系统下,进入 rt0_windows_amd64.s,执行 JMP _rt0_amd64(SB)
    在这里插入图片描述
    在这里插入图片描述
  2. 调用 _rt0_amd64(SB) 方法,该方法位于 %GOROOT%\src\runtime\asm_amd64.s
    在这里插入图片描述
  3. 该方法将调用命令参数 argc,argc 放入寄存器,随后调用 runtime·rt0_go(SB)
    在这里插入图片描述
  • 读取命令行参数。复制参数数量 argc 和参数值 argv 到栈上,参数可能有也可能没有,取决于启动程序时参数是否输入。
  • 初始化 g0 执行栈。启动 g0 协程,g0 是 Go 程序的第一个协程,且不归调度器管理,是为了调度协程而产生的协程。
  • 经过一系列判断后,开始运行时检测 runtime.check,该检测方法位于 %GOROOT%\src\runtime\runtime1.go。主要检测包括:
    在这里插入图片描述
    • 检查各种类型的长度
    • 检查指针操作
    • 检查结构体字段的偏移量
    • 检查 atomic 原子操作
    • 检查 CAS 操作
    • 检查栈大小是否为 2 的幂次
  • 初始化 runtime.args。对命令行中的参数进行处理,拷贝参数到 go 代码,参数数量赋值给 argc int32,参数值赋值给 argv **byte。
  • 执行 runtime·osinit(SB) 判断 cpu 核数,用于后续调度器的初始化 runtime·schedinit(SB)
    • 全局占空间内存分配
    • 加载命令行参数到 os.Args
    • 堆内存空间的初始化
    • 加载操作系统环境变量
    • 初始化当前系统线程
    • 垃圾回收器的参数初始化
    • 算法初始化
    • 设置 process 数量
  • 取 runtime 主函数地址 MOVQ $runtime·mainPC(SB), AX,创建启动主协程 runtime·newproc(SB),初始化调度器 M runtime·mstart(SB),调度主协程用于运行 runtime.main,runtime 的 main 方法位于 %GOROOT%\src\runtime\proc.go
  • 主协程执行主函数。执行 runtime 中的 init 方法,启动垃圾回收器,执行用户包依赖的 init 方法,最后执行用户自定义的主函数 main.main():
    在这里插入图片描述
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/694896.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言学习笔记---初始C语言005

C语言程序设计笔记---005 初识C语言三大结构语句函数数组操作符1、初识C语言三个结构2、初识函数3、初识一维数组4、初识C语言操作符4.1、算数操作符例程4.2、赋值操作符例程4.3、关系操作符例程4.4、复合操作符例程4.5、单目操作符例程4.6、条件操作符例程4.7、逻辑操作符例程…

222. 完全二叉树的节点个数

题目描述: 主要思路: 利用二分答案的思想进行求解。 首先遍历到最底下的最左结点,然后可以得到一个答案范围,然后二分求解验证即可。 具体细节见代码。 /*** Definition for a binary tree node.* struct TreeNode {* int v…

工程安全监测无线振弦采集仪在建筑物的应用

工程安全监测无线振弦采集仪在建筑物的应用 工程安全监测无线振弦采集仪是一种先进的监测设备,可以在建筑物、桥梁、隧道、大坝等工程施工或运营中进行振动监测和安全评估。其在建筑物的应用主要是针对建筑物结构的振动和变形进行监测和分析,以确保建筑…

java抽象类中的静态方法

Java的抽象类中可以包含静态方法,即类方法。尽管抽象类不能实例化,但抽象类中的静态方法是可以用抽象类直接调用的。 下面的代码示例定义了一个抽象类AbstractDemo ,其中包含一个抽象方法method,一个public静态方法showMessage。…

人工智能系统架构-应用架构

一、架构图 上图架构一个C/S架构 智能终端(C)包括智能音箱、人脸识别、人脸支付等应用和智能操作系统。 人工智能大脑(S)构成包括智能云平台、大数据平台,机器学习、深度学习,语音识别模型、图像识别模型和…

CentOS 设置系统字符集,显示为中文

环境: centos 背景: 使用vim打开含有中文的文件,中文显示为乱码。 1、 查看系统当前所用的字符集 locale 2、 安装字符集 查看系统当前安装的所有字符集中有没有 zh_CN.utf8 字符集 locale -a |grep zh_CN.utf8 假如没有&#xff0…

Linux 内存清理

1.查看内存使用情况 free -h 2.内存清理命令 清理PageCache缓存 sudo sync && echo 1 > /proc/sys/vm/drop_caches 清理dentries和inodes缓存 sudo sync && echo 2 > /proc/sys/vm/drop_caches 清理PageCache、dentries和inodes缓存 sudo sync &…

Sentieon | 每周文献-Tumor Sequencing-第三期

肿瘤测序系列文章-1 标题(英文):The relationship between genetic characteristics and clinical characteristics and the efficacy of 131 I therapy in children and adolescents with locally advanced or metastatic differentiated th…

栈的简介与实现(Java)

一、简介 栈 (Stack) 只允许在有序的线性数据集合的一端(称为栈顶 top)进行加入数据(push)和移除数据(pop)。因而按照 后进先出 一般作用于深度搜索 假设堆栈中有n个元素。 访问:O&#xff08…

一文学会Python安装和基础语法-全程干货

安装Python程序 官网Python下载地址:Python Releases for Windows | Python.org 安装3.7版本即可,版本升级可能会有较小的改动,下面要学习的都以python3.7为例 下载安装包之后直接双击无脑安装即可 新手经常遇到的问题: 1.符号…

基于VUE框架的旅游平台-计算机毕设 附源码82070

基于VUE框架的旅游平台 摘 要 改革开放以来,我国的旅游业有了非常迅速的发展,但是比较而言,我国国内旅游业发展的广度深度都远远不能适应经济发展和人民生活水平提高的需要。随着市场经济的发展和人民收入水平的进一步提高,人民对…

『Vue组件』全局注册与局部注册及组件命名

一、组件注册的方式 在Vue中组件的注册一般可以分为两种方式,你可以在main.ts或globalComponents.ts等统一管理文件中对公共组件进行注册。也可以在父组件中引入组件并在components属性中对组件进行按需注册(OptionsAPI),这样便可…

漏洞复现 飞视美 视频会议系统 Struts2 远程命令执行漏洞

0x01 阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&…

Grafana任意文件读取漏洞(CVE-2021-43798)

Grafana任意文件读取漏洞(CVE-2021-43798) 一、漏洞描述 Grafana是一个跨平台、开源的数据可视化网络应用程序平台。用户配置连接的数据源之后,Grafana可以在网络浏览器里显示数据图表和警告。 二、漏洞影响范围 影响版本: Gr…

antv-g6—在vue项目中实现网格拓扑流程图自定义绘制

实现效果图 这个是自己写着玩的,利用antv/g6自定义绘制流程图,然后保存到localstorage中,在左侧表格展示,还可以通过表格操作来查看对应的流程图以及删除; 这里特别注意一下,antv/g6版本是1.2.8&#xff0…

ModaHub魔搭社区:向量数据库MIlvus服务端配置(二)

目录 storage 区域 wal 区域 cache 区域 storage 区域 | 参数 | 说明 | 类型 | 默认值 | | ——————————————- | —————————————————————————————— | ——————————————————————————————- | ————…

解决 mac 系统报zsh: command not found: npm 问题

文章目录 1、报错zsh: command not found: npm2、解决办法 1、报错zsh: command not found: npm 根据提示:zsh: command not found: npm。说明没有找到 npm 命令,这说明有两种情况: 一是:你根本就没有安装 nodejs 的环境&#xf…

git add 时报错 warning: in the working copy of ‘package-lock.json‘, LF will...

问题: 执行git add . 时报错 原因: 换行符的问题, Windows下换行符和Unix下的换行符不一样,git会自动转换。 解决办法: 执行命令: git config --global core.autocrlf false 问题解决:

Windows网络服务综测刷题

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​ 前言 本章将会讲解Windows网络服务的刷题 一.刷题 在Windows Server 2016系统中&#xf…

【openpyxl】总结最近使用到的openpyxl方法

这里写自定义目录标题 单元格嵌入图片调节行高和列宽合并单元格自动换行按列插入数据tableWidget数据导出到excel 单元格嵌入图片 from openpyxl.drawing.image import Image from openpyxl.drawing.spreadsheet_drawing import AnchorMarker, TwoCellAnchor from openpyxl.wor…