不久前有人问了一个问题,关于 Golang 实际上如何在像a, b = b, a.
为了回答这个问题,我拿出了我的 Golang 编译器,戴上了我的思维帽,并为上述问题制作了一个答案。所以问题应该是独立的,所以为了简洁起见,我的答案被截断了:
要弄清楚编译器如何生成本机代码,我们需要查看它生成的汇编代码,这些代码由链接器转换为机器代码。
我写了一个小 Go 程序来帮助解决这个问题:
package main
import "fmt"
func main() { fmt.Println(myfunction()) }
func myfunction() []int {
a, b := 10, 5
b, a = a, b
return []int{a, b}
}
使用go tool compile -S > swap.s,我找到了这四行,它们对应myfunction于 Go 代码中的前两行:(注意这是针对我的 64 位机器;输出会在其他架构(如 32 位)上有所不同)
0x0028 00040 (swap.go:10) MOVQ $10, CX ; var a = 10
0x002f 00047 (swap.go:10) MOVQ $5, AX ; var b = 5
0x0036 00054 (swap.go:11) MOVQ CX, "".b+16(SP) ; copy a to *b+16
0x003b 00059 (swap.go:11) MOVQ AX, "".a+24(SP) ; copy b to *a+24
查看关于 asm 的 Golang 文档,我们可以看到汇编程序使用间接来处理值。
当程序运行时,CPU 足够聪明,可以看到发生了什么,并使用寄存器来避免覆盖现有值。
这是完整的拆解,如果您有兴趣。
根据我对(英特尔)x86 组装的微薄知识,我的 评论获得了 6 票,我的回答获得了接受和 3 票。
Golang程序集的四行实际上是做什么的?我的回答正确吗?
我问是因为我链接的文档不是很(根本)详尽。
临摹微笑
开满天机
相关分类