6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

这篇具有很好参考价值的文章主要介绍了6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、Go版本

go1.14.15

2、汇编基础

  • 推荐阅读:GO汇编语言简介

  • 推荐阅读:A Quick Guide to Go's Assembler - The Go Programming Language

  • 精简指令集

    • 数据传输: MOV/LEA

    • 跳转指令: CMP/TEST/JMP/JCC

    • 栈指令: PUSH/POP

    • 函数调用指令: CALL/RET

    • 算术指令: ADD/SUB/MUL/DIV

    • 逻辑指令: AND/OR/XOR/NOT

    • 移位指令: SHL/SHR

    • JCC有条件跳转: JEQ/JNE/JLT/JLE/JGT/JGE

    • 还有针对无符号数的比较条件

  • MOV指令

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

注:图片来源于GO汇编语言简介

   

  • 伪寄存器

    • SB: 静态基址指针, 全局符号

    • FP: 帧指针, 参数和局部变量

    • SP: 栈指针, 栈的顶端

    • PC: 程序计数器, 跳转和分支

    • 注:伪寄存器仅仅存在于Go汇编中

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

  • 伪寄存器用法

    • GLOBL text(SB),$1: 全局变量

    • MOVQ a+0(FP) AX: 函数参数

    • MOVQ b+8(SP) AX: 局部变量

    • JMP 2(PC): 向前跳转, 常用于宏函数

    • JMP -2(PC): 向后跳转, 常用于宏函数

3、示例代码

package main


func main() {

   n := 10

   println(read(&n))

}


//go:noinline
func read(p *int) (v int) {

   v = *p

   return

}
  • //go:noinline:禁止Go对函数进行内联

  • 内联:内联是一种手动或编译器优化,用于将简短函数的调用替换为函数体本身。这么做的原因是它可以消除函数调用本身的开销,也使得编译器能更高效地执行其他的优化策略

  • 使用objdump工具反编译

4、结合chatGPT反编译调试

go build s1.go                                  //编译

go tool objdump -S -s "main.read" .\s3.exe      //反编译

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

  • 图中是用go自带的objdump工具对main.read反编译得到的汇编指令

  • 不懂就问,咱们直接问chatGPT这段汇编指令的含义(首先需要给chatGPT一些引导和背景介绍),如下图

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

  • 上面解释的很清楚了,为了进一步理解这些指令的含义,追问

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

5、指针

  • 指针本身是一个无符号整型

package main

func main() {

   n := int32(10)

   println(read32(&n))

}

//go:noinline
func read32(p *int32) (v int32) {

   v = *p

   return

}

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

可以看到上述汇编指令中,第一行从参数p中取地址值的操作没变化,只是从AX寄存器中取值的时候,命令有MOVQ(8字节)变为MOVL(4字节),可见不同类型的指针地址本身是一样的类型(无符号整型)

  • 取地址

package main

var n int

func main() {

   println(addr())

}

//go:noinline
func addr() (p *int) {

   return &n

}

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

直接问chatGPT,给出的解释是:

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理

    • 从上图可以看到全局变量n是存在main包的静态基地址上(SB),被不同的函数和代码块共享访问,SB 是静态基地址的缩写,它是指向静态基地址的寄存器。因此,"main.n(SB)" 就是通过 SB 指向 main 包的静态基地址上的 n 变量。

    • LEAQ 指令将全局变量 n 的有效地址存储到 AX 寄存器中,这样 AX 寄存器就包含了 n 变量的地址,可以用于读取或写入该变量的值。

    • LEAQ 指令用于将有效地址存储到一个寄存器中

  • 强制类型转换

package main

import "unsafe"

func main() {

   p := 3

   convert(&p)

}

//go:noinline
func convert(p *int) {

   q := (*int32)(unsafe.Pointer(p))

   *q = 0

}

6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理文章来源地址https://www.toymoban.com/news/detail-442417.html

  • 这段汇编代码是将一个指向int类型变量的指针,转换为指向int32类型变量的指针,并将其所指向的内存空间的值设置为0
  • 把指针的类型强转换为int32后,原本的MOVQ指令变成了MOVL,没有产生任何额外指令,所以转换效率是非常高的

到了这里,关于6.Go语言学习笔记-结合chatGPT辅助学习Go语言底层原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • go语言学习笔记1

    ​ GoLang是一种静态强类型、编译型、并发型,并具有 垃圾回收 功能的编程语言;它可以在不损失应用程序性能的情况下极大的降低代码的复杂性,还可以发挥多核处理器同步多工的优点,并可解决面向对象程序设计的麻烦,并帮助程序设计师处理琐碎但重要的内存管理问题

    2024年02月12日
    浏览(34)
  • Go语言学习笔记(三)

    教程:文档 - Go 编程语言 (studygolang.com) 在call-module-code需要注意,需要在hello目录下操作 这是一个在Go项目的模块管理中的命令。在Go的模块管理工具( go mod )中,这个命令用于修改模块依赖关系。 具体来说, go mod edit -replace example.com/greetings=../greetings  这个命令的作用是:

    2024年02月02日
    浏览(33)
  • Go语言学习笔记(狂神说)

    视频地址:https://www.bilibili.com/video/BV1ae41157o9 聊聊Go语言的历史-KuangStudy-文章 下面列举的是原生使用Go语言进行开发的部分项目。 Docker Docker 是一种操作系统层面的虚拟化技术,可以在操作系统和应用程序之间进行隔离,也可以称之为容器。Docker 可以在一台物理服务器上快速

    2024年02月15日
    浏览(30)
  • 《Go 语言第一课》课程学习笔记(五)

    Go 语言中有一个特殊的函数:main 包中的 main 函数,也就是 main.main,它是所有 Go 可执行程序的用户层执行逻辑的入口函数。 Go 程序在用户层面的执行逻辑,会在这个函数内按照它的调用顺序展开。 main 函数的函数原型非常简单,没有参数也没有返回值。 Go 语言要求:可执行

    2024年02月12日
    浏览(32)
  • 《Go 语言第一课》课程学习笔记(十三)

    Go 语言从设计伊始,就不支持经典的面向对象语法元素,比如类、对象、继承,等等,但 Go 语言仍保留了名为“方法(method)”的语法元素。当然,Go 语言中的方法和面向对象中的方法并不是一样的。Go 引入方法这一元素,并不是要支持面向对象编程范式,而是 Go 践行组合

    2024年02月10日
    浏览(28)
  • 《Go 语言第一课》课程学习笔记(二)

    在 Go 语言中编写一个可以打印出“hello,world”的示例程序,我们只需要简单两步,一是创建文件夹,二是开始编写和运行。 通常来说,Go 不会限制我们存储代码的位置,建议创建一个可以集合所有项目的根文件夹(比如:~/goprojects),然后将所有的项目都放在里面。 对于

    2024年02月12日
    浏览(31)
  • 《Go 语言第一课》课程学习笔记(八)

    Go 语言的类型大体可分为基本数据类型、复合数据类型和接口类型这三种。 其中,我们日常 Go 编码中使用最多的就是基本数据类型,而基本数据类型中使用占比最大的又是数值类型。 Go 语言的整型,主要用来表示现实世界中整型数量等。它可以分为平台无关整型和平台相关

    2024年02月12日
    浏览(36)
  • 《Go 语言第一课》课程学习笔记(十二)

    在 Go 语言中,函数是唯一一种基于特定输入,实现特定任务并可返回任务执行结果的代码块(Go 语言中的方法本质上也是函数)。 在 Go 中,我们定义一个函数的最常用方式就是使用函数声明。 第一部分是 func,Go 函数声明必须以 func 开始。 第二部分是函数名。

    2024年02月11日
    浏览(35)
  • 《Go 语言第一课》课程学习笔记(九)

    Go 语言在常量方面的创新包括下面这几点: 支持无类型常量; 支持隐式自动转型; 可用于实现枚举。 Go 语言的常量是一种在源码编译期间被创建的语法元素。这是在说这个元素的值可以像变量那样被初始化,但它的初始化表达式必须是在编译期间可以求出值来的。 Go 常量

    2024年02月12日
    浏览(31)
  • 《Go 语言第一课》课程学习笔记(十一)

    针对程序的分支结构,Go 提供了 if 和 switch-case 两种语句形式;而针对循环结构,Go 只保留了 for 这一种循环语句形式。 if 语句 if 语句是 Go 语言中提供的一种分支控制结构,它也是 Go 中最常用、最简单的分支控制结构。它会根据布尔表达式的值,在两个分支中选择一个执行

    2024年02月11日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包