Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 这就是Golang执行多重任务的方式吗?_Assembly_Go - Fatal编程技术网

Assembly 这就是Golang执行多重任务的方式吗?

Assembly 这就是Golang执行多重任务的方式吗?,assembly,go,Assembly,Go,不久前有人问Golang实际上是如何在语句中交换变量的,比如A,b=b,A 为了回答这个问题,我拿出了我的Golang编译器,戴上我的思考帽,精心设计了这个问题。所以问题应该是独立的,为了简洁起见,我的答案是: 要了解编译器如何生成本机代码,我们需要了解 它生成的汇编代码,由 链接器 我写了一个小围棋程序来帮助解决这个问题: package main import "fmt" func main() { fmt.Println(myfunction()) } func myfunct

不久前有人问Golang实际上是如何在语句中交换变量的,比如
A,b=b,A

为了回答这个问题,我拿出了我的Golang编译器,戴上我的思考帽,精心设计了这个问题。所以问题应该是独立的,为了简洁起见,我的答案是:

要了解编译器如何生成本机代码,我们需要了解 它生成的汇编代码,由 链接器

我写了一个小围棋程序来帮助解决这个问题:

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
,我找到了这四行,它们对应于第一行 Go代码中的两行
myfunction
(注意这是我的64位代码 机器;输出将在其他架构(如32位)上有所不同

看一下,我们可以看到汇编程序使用间接方式来处理这些值

当程序运行时,CPU足够智能,可以看到发生了什么 并使用寄存器避免覆盖现有值

我对(英特尔)x86汇编知之甚少,因此获得了6票,我的回答得到了接受和3票

Golang assembly的四条生产线实际上在做什么?我的回答正确吗

我问这个问题是因为我链接到的内容不是很详尽

a, b := 10, 5
b, a = a, b

0x0028 00040 (swap.go:10) MOVQ    $10, CX         ; CX = 10
0x002f 00047 (swap.go:10) MOVQ    $5, AX          ; AX = 5
0x0036 00054 (swap.go:11) MOVQ    CX, "".b+16(SP) ; b = CX or *(SP+16) = CX
0x003b 00059 (swap.go:11) MOVQ    AX, "".a+24(SP) ; a = AX or *(SP+24) = CX 

CX
AX
SP
是寄存器
a
b
分别是SP+24和SP+16堆栈上的变量。

它将常量10和5加载到CPU寄存器中,然后将寄存器存储到为变量
a
b
保留的堆栈位置

这相当于:

 CX := 10
 AX := 5
 b := CX
 a := AX
注意:半优化编译器应将其优化为直接将常量存储到堆栈位置的代码:

 b := 10
 a := 5
或者更好地完全消除变量:

 return []int{5, 10}

我不知道那个奇怪的ass语法是什么意思,但在分解后它变成了
mov rcx,10\mov rax,5\mov[rsp+16],rcx\mov[rsp+24],rax
(这对于64位代码来说几乎是合理的,但它浪费了mov immediate上无用的REX.W前缀,只需要一个微小的立即数)@harold它是go-asm,而不是x86
 return []int{5, 10}