0%

Golang写时复制是否是原子性的?

Golang在生成汇编语句的时候,赋值是一句话,所以:COW Copy-On-Write是原子性的

先说一下我这边的一个简化场景吧,有一个定时任务定时从数据库获取数据,也就是对应实例代码中的getNewProject(),获取完数据后,会直接赋给变量projectMap(projectMap其实就是作为一个缓存来用的);还会有程序从projectMap获取对应的信息。

这个场景其实就是一个简单的写时复制。对于获取在赋值过程中,获取到旧值,也是允许的。

有个疑问点就是在赋值的这个操作是不是原子的呢?

比如示例代码中的第8行。

验证代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

var (
projectMap = make(map[string]*Project)
)

func main() {
projectMap = getNewProject()
}

func getNewProject() map[string]*Project {
items := make(map[string]*Project)

item := new(Project)
item.ID = "project_id"
item.Name = "project_name"

items[item.ID] = item
return items

}

type Project struct {
ID string `json:"id"`
Name string `json:"name"`
}

在网上也找到一些资料,说是原子性的:

但终究还是自己探索一下的比较好对吧,哈哈。

要想看这个赋值操作是不是原子性的,那咱们看下汇编代码吧。
查看汇编,咱们分为两步:

  • 编译golang代码为.o文件
  • 反编译.o文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    PS D:\Code\Golang\github\jiankunking\cow-test> go tool compile -N -l main\main.go    
    PS D:\Code\Golang\github\jiankunking\cow-test> go tool objdump .\main.o
    TEXT "".main(SB) gofile..D:/Code/Golang/github/jiankunking/cow-test/main/main.go
    main.go:7 0x22f1 493b6610 CMPQ 0x10(R14), SP
    main.go:7 0x22f5 763e JBE 0x2335
    main.go:7 0x22f7 4883ec08 SUBQ $0x8, SP
    main.go:7 0x22fb 48892c24 MOVQ BP, 0(SP)
    main.go:7 0x22ff 488d2c24 LEAQ 0(SP), BP
    main.go:8 0x2303 e800000000 CALL 0x2308 [1:5]R_CALL:"".getNewProject
    main.go:8 0x2308 833d0000000000 CMPL $0x0, 0(IP) [2:6]R_PCREL:runtime.writeBarrier+-1
    main.go:8 0x230f 6690 NOPW
    main.go:8 0x2311 7402 JE 0x2315
    main.go:8 0x2313 eb09 JMP 0x231e
    main.go:8 0x2315 48890500000000 MOVQ AX, 0(IP) [3:7]R_PCREL:"".projectMap
    main.go:8 0x231c eb0e JMP 0x232c
    main.go:8 0x231e 488d3d00000000 LEAQ 0(IP), DI [3:7]R_PCREL:"".projectMap
    main.go:8 0x2325 e800000000 CALL 0x232a [1:5]R_CALL:runtime.gcWriteBarrier<1>
    main.go:8 0x232a eb00 JMP 0x232c
    main.go:9 0x232c 488b2c24 MOVQ 0(SP), BP
    main.go:9 0x2330 4883c408 ADDQ $0x8, SP
    main.go:9 0x2334 c3 RET
    main.go:7 0x2335 e800000000 CALL 0x233a [1:5]R_CALL:runtime.morestack_noctxt
    main.go:7 0x233a ebb5 JMP "".main(SB)

    TEXT "".getNewProject(SB) gofile..D:/Code/Golang/github/jiankunking/cow-test/main/main.go
    main.go:11 0x233c 493b6610 CMPQ 0x10(R14), SP
    main.go:11 0x2340 0f8600010000 JBE 0x2446
    main.go:11 0x2346 4883ec58 SUBQ $0x58, SP
    main.go:11 0x234a 48896c2450 MOVQ BP, 0x50(SP)
    main.go:11 0x234f 488d6c2450 LEAQ 0x50(SP), BP
    main.go:11 0x2354 48c744242000000000 MOVQ $0x0, 0x20(SP)
    main.go:12 0x235d e800000000 CALL 0x2362 [1:5]R_CALL:runtime.makemap_small<1>
    main.go:12 0x2362 4889442428 MOVQ AX, 0x28(SP)
    main.go:14 0x2367 488d0500000000 LEAQ 0(IP), AX [3:7]R_PCREL:type."".Project
    main.go:14 0x236e e800000000 CALL 0x2373 [1:5]R_CALL:runtime.newobject<1>
    main.go:14 0x2373 4889442430 MOVQ AX, 0x30(SP)
    main.go:15 0x2378 48c740080a000000 MOVQ $0xa, 0x8(AX)
    main.go:15 0x2380 833d0000000000 CMPL $0x0, 0(IP) [2:6]R_PCREL:runtime.writeBarrier+-1
    main.go:15 0x2387 7402 JE 0x238b
    main.go:15 0x2389 eb0c JMP 0x2397
    main.go:15 0x238b 488d1500000000 LEAQ 0(IP), DX [3:7]R_PCREL:go.string."project_id"
    main.go:15 0x2392 488910 MOVQ DX, 0(AX)
    main.go:15 0x2395 eb11 JMP 0x23a8
    main.go:15 0x2397 4889c7 MOVQ AX, DI
    main.go:15 0x239a 488d1500000000 LEAQ 0(IP), DX [3:7]R_PCREL:go.string."project_id"
    main.go:15 0x23a1 e800000000 CALL 0x23a6 [1:5]R_CALL:runtime.gcWriteBarrierDX
    main.go:15 0x23a6 eb00 JMP 0x23a8
    main.go:16 0x23a8 488b542430 MOVQ 0x30(SP), DX
    main.go:16 0x23ad 8402 TESTB AL, 0(DX)
    main.go:16 0x23af 48c742180c000000 MOVQ $0xc, 0x18(DX)
    main.go:16 0x23b7 488d7a10 LEAQ 0x10(DX), DI
    main.go:16 0x23bb 833d0000000000 CMPL $0x0, 0(IP) [2:6]R_PCREL:runtime.writeBarrier+-1
    main.go:16 0x23c2 7402 JE 0x23c6
    main.go:16 0x23c4 eb0d JMP 0x23d3
    main.go:16 0x23c6 488d3500000000 LEAQ 0(IP), SI [3:7]R_PCREL:go.string."project_name"
    main.go:16 0x23cd 48897210 MOVQ SI, 0x10(DX)
    main.go:16 0x23d1 eb10 JMP 0x23e3
    main.go:16 0x23d3 488d1500000000 LEAQ 0(IP), DX [3:7]R_PCREL:go.string."project_name"
    main.go:16 0x23da 6690 NOPW
    main.go:16 0x23dc e800000000 CALL 0x23e1 [1:5]R_CALL:runtime.gcWriteBarrierDX
    main.go:16 0x23e1 eb00 JMP 0x23e3
    main.go:18 0x23e3 488b542430 MOVQ 0x30(SP), DX
    main.go:18 0x23e8 8402 TESTB AL, 0(DX)
    main.go:18 0x23ea 488b0a MOVQ 0(DX), CX
    main.go:18 0x23ed 488b7a08 MOVQ 0x8(DX), DI
    main.go:18 0x23f1 48894c2440 MOVQ CX, 0x40(SP)
    main.go:18 0x23f6 48897c2448 MOVQ DI, 0x48(SP)
    main.go:18 0x23fb 488b5c2428 MOVQ 0x28(SP), BX
    main.go:18 0x2400 488d0500000000 LEAQ 0(IP), AX [3:7]R_PCREL:type.map[string]*"".Project
    main.go:18 0x2407 e800000000 CALL 0x240c [1:5]R_CALL:runtime.mapassign_faststr<1>
    main.go:18 0x240c 4889442438 MOVQ AX, 0x38(SP)
    main.go:18 0x2411 8400 TESTB AL, 0(AX)
    main.go:18 0x2413 488b542430 MOVQ 0x30(SP), DX
    main.go:18 0x2418 833d0000000000 CMPL $0x0, 0(IP) [2:6]R_PCREL:runtime.writeBarrier+-1
    main.go:18 0x241f 7402 JE 0x2423
    main.go:18 0x2421 eb05 JMP 0x2428
    main.go:18 0x2423 488910 MOVQ DX, 0(AX)
    main.go:18 0x2426 eb0a JMP 0x2432
    main.go:18 0x2428 4889c7 MOVQ AX, DI
    main.go:18 0x242b e800000000 CALL 0x2430 [1:5]R_CALL:runtime.gcWriteBarrierDX
    main.go:18 0x2430 eb00 JMP 0x2432
    main.go:19 0x2432 488b442428 MOVQ 0x28(SP), AX
    main.go:19 0x2437 4889442420 MOVQ AX, 0x20(SP)
    main.go:19 0x243c 488b6c2450 MOVQ 0x50(SP), BP
    main.go:19 0x2441 4883c458 ADDQ $0x58, SP
    main.go:19 0x2445 c3 RET
    main.go:11 0x2446 e800000000 CALL 0x244b [1:5]R_CALL:runtime.morestack_noctxt
    main.go:11 0x244b e9ecfeffff JMP "".getNewProject(SB)

    TEXT "".init(SB) gofile..D:/Code/Golang/github/jiankunking/cow-test/main/main.go
    main.go:4 0x2450 493b6610 CMPQ 0x10(R14), SP
    main.go:4 0x2454 763e JBE 0x2494
    main.go:4 0x2456 4883ec08 SUBQ $0x8, SP
    main.go:4 0x245a 48892c24 MOVQ BP, 0(SP)
    main.go:4 0x245e 488d2c24 LEAQ 0(SP), BP
    main.go:4 0x2462 e800000000 CALL 0x2467 [1:5]R_CALL:runtime.makemap_small<1>
    main.go:4 0x2467 833d0000000000 CMPL $0x0, 0(IP) [2:6]R_PCREL:runtime.writeBarrier+-1
    main.go:4 0x246e 6690 NOPW
    main.go:4 0x2470 7402 JE 0x2474
    main.go:4 0x2472 eb09 JMP 0x247d
    main.go:4 0x2474 48890500000000 MOVQ AX, 0(IP) [3:7]R_PCREL:"".projectMap
    main.go:4 0x247b eb0e JMP 0x248b
    main.go:4 0x247d 488d3d00000000 LEAQ 0(IP), DI [3:7]R_PCREL:"".projectMap
    main.go:4 0x2484 e800000000 CALL 0x2489 [1:5]R_CALL:runtime.gcWriteBarrier<1>
    main.go:4 0x2489 eb00 JMP 0x248b
    main.go:4 0x248b 488b2c24 MOVQ 0(SP), BP
    main.go:4 0x248f 4883c408 ADDQ $0x8, SP
    main.go:4 0x2493 c3 RET
    main.go:4 0x2494 e800000000 CALL 0x2499 [1:5]R_CALL:runtime.morestack_noctxt
    main.go:4 0x2499 ebb5 JMP "".init(SB)

    TEXT type..eq."".Project(SB) gofile..<autogenerated>
    gofile..<autogenerated>:1 0x2713 493b6610 CMPQ 0x10(R14), SP
    gofile..<autogenerated>:1 0x2717 0f8610010000 JBE 0x282d
    gofile..<autogenerated>:1 0x271d 4883ec58 SUBQ $0x58, SP
    gofile..<autogenerated>:1 0x2721 48896c2450 MOVQ BP, 0x50(SP)
    gofile..<autogenerated>:1 0x2726 488d6c2450 LEAQ 0x50(SP), BP
    gofile..<autogenerated>:1 0x272b 4889442460 MOVQ AX, 0x60(SP)
    gofile..<autogenerated>:1 0x2730 48895c2468 MOVQ BX, 0x68(SP)
    gofile..<autogenerated>:1 0x2735 c644241e00 MOVB $0x0, 0x1e(SP)
    gofile..<autogenerated>:1 0x273a 488b542460 MOVQ 0x60(SP), DX
    gofile..<autogenerated>:1 0x273f 488b5208 MOVQ 0x8(DX), DX
    gofile..<autogenerated>:1 0x2743 4889542428 MOVQ DX, 0x28(SP)
    gofile..<autogenerated>:1 0x2748 488b542468 MOVQ 0x68(SP), DX
    gofile..<autogenerated>:1 0x274d 488b5208 MOVQ 0x8(DX), DX
    gofile..<autogenerated>:1 0x2751 4889542420 MOVQ DX, 0x20(SP)
    gofile..<autogenerated>:1 0x2756 4839542428 CMPQ DX, 0x28(SP)
    gofile..<autogenerated>:1 0x275b 7405 JE 0x2762
    gofile..<autogenerated>:1 0x275d e9b3000000 JMP 0x2815
    gofile..<autogenerated>:1 0x2762 eb00 JMP 0x2764
    gofile..<autogenerated>:1 0x2764 488b542460 MOVQ 0x60(SP), DX
    gofile..<autogenerated>:1 0x2769 488b5218 MOVQ 0x18(DX), DX
    gofile..<autogenerated>:1 0x276d 4889542420 MOVQ DX, 0x20(SP)
    gofile..<autogenerated>:1 0x2772 488b542468 MOVQ 0x68(SP), DX
    gofile..<autogenerated>:1 0x2777 488b5218 MOVQ 0x18(DX), DX
    gofile..<autogenerated>:1 0x277b 4889542428 MOVQ DX, 0x28(SP)
    gofile..<autogenerated>:1 0x2780 4839542420 CMPQ DX, 0x20(SP)
    gofile..<autogenerated>:1 0x2785 7405 JE 0x278c
    gofile..<autogenerated>:1 0x2787 e987000000 JMP 0x2813
    gofile..<autogenerated>:1 0x278c eb00 JMP 0x278e
    gofile..<autogenerated>:1 0x278e 488b542460 MOVQ 0x60(SP), DX
    gofile..<autogenerated>:1 0x2793 488b5208 MOVQ 0x8(DX), DX
    gofile..<autogenerated>:1 0x2797 4889542428 MOVQ DX, 0x28(SP)
    gofile..<autogenerated>:1 0x279c 488b542460 MOVQ 0x60(SP), DX
    gofile..<autogenerated>:1 0x27a1 488b12 MOVQ 0(DX), DX
    gofile..<autogenerated>:1 0x27a4 4889542448 MOVQ DX, 0x48(SP)
    gofile..<autogenerated>:1 0x27a9 488b542468 MOVQ 0x68(SP), DX
    gofile..<autogenerated>:1 0x27ae 488b1a MOVQ 0(DX), BX
    gofile..<autogenerated>:1 0x27b1 48895c2440 MOVQ BX, 0x40(SP)
    gofile..<autogenerated>:1 0x27b6 488b4c2428 MOVQ 0x28(SP), CX
    gofile..<autogenerated>:1 0x27bb 488b442448 MOVQ 0x48(SP), AX
    gofile..<autogenerated>:1 0x27c0 e800000000 CALL 0x27c5 [1:5]R_CALL:runtime.memequal<1>
    gofile..<autogenerated>:1 0x27c5 8844241f MOVB AL, 0x1f(SP)
    gofile..<autogenerated>:1 0x27c9 84c0 TESTL AL, AL
    gofile..<autogenerated>:1 0x27cb 7502 JNE 0x27cf
    gofile..<autogenerated>:1 0x27cd eb41 JMP 0x2810
    gofile..<autogenerated>:1 0x27cf eb00 JMP 0x27d1
    gofile..<autogenerated>:1 0x27d1 488b542460 MOVQ 0x60(SP), DX
    gofile..<autogenerated>:1 0x27d6 488b5218 MOVQ 0x18(DX), DX
    gofile..<autogenerated>:1 0x27da 4889542428 MOVQ DX, 0x28(SP)
    gofile..<autogenerated>:1 0x27df 488b542460 MOVQ 0x60(SP), DX
    gofile..<autogenerated>:1 0x27e4 488b5210 MOVQ 0x10(DX), DX
    gofile..<autogenerated>:1 0x27e8 4889542438 MOVQ DX, 0x38(SP)
    gofile..<autogenerated>:1 0x27ed 488b542468 MOVQ 0x68(SP), DX
    gofile..<autogenerated>:1 0x27f2 488b5a10 MOVQ 0x10(DX), BX
    gofile..<autogenerated>:1 0x27f6 48895c2430 MOVQ BX, 0x30(SP)
    gofile..<autogenerated>:1 0x27fb 488b4c2428 MOVQ 0x28(SP), CX
    gofile..<autogenerated>:1 0x2800 488b442438 MOVQ 0x38(SP), AX
    gofile..<autogenerated>:1 0x2805 e800000000 CALL 0x280a [1:5]R_CALL:runtime.memequal<1>
    gofile..<autogenerated>:1 0x280a 8844241e MOVB AL, 0x1e(SP)
    gofile..<autogenerated>:1 0x280e eb0e JMP 0x281e
    gofile..<autogenerated>:1 0x2810 eb05 JMP 0x2817
    gofile..<autogenerated>:1 0x2812 90 NOPL
    gofile..<autogenerated>:1 0x2813 eb02 JMP 0x2817
    gofile..<autogenerated>:1 0x2815 eb00 JMP 0x2817
    gofile..<autogenerated>:1 0x2817 c644241e00 MOVB $0x0, 0x1e(SP)
    gofile..<autogenerated>:1 0x281c eb00 JMP 0x281e
    gofile..<autogenerated>:1 0x281e 0fb644241e MOVZX 0x1e(SP), AX
    gofile..<autogenerated>:1 0x2823 488b6c2450 MOVQ 0x50(SP), BP
    gofile..<autogenerated>:1 0x2828 4883c458 ADDQ $0x58, SP
    gofile..<autogenerated>:1 0x282c c3 RET
    gofile..<autogenerated>:1 0x282d 4889442408 MOVQ AX, 0x8(SP)
    gofile..<autogenerated>:1 0x2832 48895c2410 MOVQ BX, 0x10(SP)
    gofile..<autogenerated>:1 0x2837 e800000000 CALL 0x283c [1:5]R_CALL:runtime.morestack_noctxt
    gofile..<autogenerated>:1 0x283c 488b442408 MOVQ 0x8(SP), AX
    gofile..<autogenerated>:1 0x2841 488b5c2410 MOVQ 0x10(SP), BX
    gofile..<autogenerated>:1 0x2846 e9c8feffff JMP type..eq."".Project(SB)
    PS D:\Code\Golang\github\jiankunking\cow-test>

先从汇编代码中摘取出,第8行代码对应的汇编

1
2
3
4
5
6
7
8
9
10
main.go:8             0x2303                  e800000000              CALL 0x2308             [1:5]R_CALL:"".getNewProject        
main.go:8 0x2308 833d0000000000 CMPL $0x0, 0(IP) [2:6]R_PCREL:runtime.writeBarrier+-1
main.go:8 0x230f 6690 NOPW
main.go:8 0x2311 7402 JE 0x2315
main.go:8 0x2313 eb09 JMP 0x231e
main.go:8 0x2315 48890500000000 MOVQ AX, 0(IP) [3:7]R_PCREL:"".projectMap
main.go:8 0x231c eb0e JMP 0x232c
main.go:8 0x231e 488d3d00000000 LEAQ 0(IP), DI [3:7]R_PCREL:"".projectMap
main.go:8 0x2325 e800000000 CALL 0x232a [1:5]R_CALL:runtime.gcWriteBarrier<1>
main.go:8 0x232a eb00 JMP 0x232c

从汇编代码中可以看出,赋值的核心在下面这几句:

1
2
3
4
5
6
// 将AX寄存器中的值赋给0(IP)
main.go:8 0x2315 48890500000000 MOVQ AX, 0(IP) [3:7]R_PCREL:"".projectMap
// 跳转
main.go:8 0x231c eb0e JMP 0x232c
// 将0(IP)中值的地址赋给DI
main.go:8 0x231e 488d3d00000000 LEAQ 0(IP), DI [3:7]R_PCREL:"".projectMap

从汇编可以看到赋值是只有一步,但获取值及赋值是分开的,也就是说对于写时复制这种场景来说,直接赋值是没有问题的

基础知识补充:

MOVQ

  • movb(8位)、movw(16位)、movl(32位)、movq(64位)

  • 寄存器寻址:

    1
    2
    movl %eax, %edx
    eax -> edx

https://blog.csdn.net/luoyhang003/article/details/46786591/

TESTB

TEST指令的行为与AND指令一样,除了不改变目的寄存器的值。例如,testq %rax, %rax 用来检查 %rax 是负数、零、还是正数。

LEAQ vs MOVQ

https://stackoverflow.com/questions/1699748/what-is-the-difference-between-mov-and-lea

PCDATA

https://www.cnblogs.com/binHome/p/13034103.html

CMPL

1
2
3
CMPL %eax,%ebx
==>
[ebx]-[eax],就是把第二个数减去第一个数

JMP

无条件转移指令
JMP 389无条件转至0x0185地址处(十进制389转换成十六进制0x0185)

CALL

调用函数
CALL runtime.printnl(SB)表示通过printnl函数的内存地址发起调用

伪计数器

FP: Frame pointer: arguments and locals.(指向当前栈帧)
PC: Program counter: jumps and branches.(指向指令地址)
SB: Static base pointer: global symbols.(指向全局符号表)
SP: Stack pointer: top of stack.(指向当前栈顶部)
注意: 栈是向下整长 golang的汇编是调用者维护参数返回值跟返回地址。所以FP的值小于参数跟返回值

本机环境

x86-64( 又称x64,即英文词64-bit extended,64位拓展 的简写)是x86架构的64位拓展,向后兼容于16位及32位的x86架构。x64于1999年由AMD设计,AMD首次公开64位集以扩展给x86,称为“AMD64”。

编译命令详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
PS D:\Code\Golang\github\jiankunking\cow-test> go tool compile -help
usage: compile [options] file.go...
-% int
debug non-static initializers
-+ compiling runtime
-B disable bounds checking
-C disable printing of columns in error messages
-D path
set relative path for local imports
-E debug symbol export
-G accept generic code (default 3)
-I directory
add directory to import search path
-K debug missing line numbers
-L show full file names in error messages
-N disable optimizations
-S print assembly listing
-V print version and exit
-W debug parse tree after type checking
-asan
build code compatible with C/C++ address sanitizer
-asmhdr file
write assembly header to file
-bench file
append benchmark times to file
-blockprofile file
write block profile to file
-buildid id
record id as the build id in the export metadata
-c int
concurrency during compilation (1 means no concurrency) (default 1)
-clobberdead
clobber dead stack slots (for debugging)
-clobberdeadreg
clobber dead registers (for debugging)
-complete
compiling complete package (no C or assembly)
-cpuprofile file
write cpu profile to file
-d value
enable debugging settings; try -d help
-dwarf
generate DWARF symbols (default true)
-dwarfbasentries
use base address selection entries in DWARF (default true)
-dwarflocationlists
add location lists to DWARF in optimized mode (default true)
-dynlink
support references to Go symbols defined in other shared libraries
-e no limit on number of errors reported
-embedcfg file
read go:embed configuration from file
-gendwarfinl int
generate DWARF inline info records (default 2)
-goversion string
required version of the runtime
-h halt on error
-importcfg file
read import configuration from file
-importmap definition
add definition of the form source=actual to import map
-installsuffix suffix
set pkg directory suffix
-j debug runtime-initialized variables
-json string
version,file for JSON compiler/optimizer detail output
-l disable inlining
-lang string
Go language version source code expects
-linkobj file
write linker-specific object to file
-linkshared
generate code that will be linked against Go shared libraries
-live
debug liveness analysis
-m print optimization decisions
-memprofile file
write memory profile to file
-memprofilerate rate
set runtime.MemProfileRate to rate
-msan
build code compatible with C/C++ memory sanitizer
-mutexprofile file
write mutex profile to file
-nolocalimports
reject local (relative) imports
-o file
write output to file
-p path
set expected package import path
-pack
write to file.a instead of file.o
-r debug generated wrappers
-race
enable race detector
-shared
generate code that can be linked into a shared library
-smallframes
reduce the size limit for stack allocated objects
-spectre list
enable spectre mitigations in list (all, index, ret)
-std
compiling standard library
-symabis file
read symbol ABIs from file
-t enable tracing for debugging the compiler
-traceprofile file
write an execution trace to file
-trimpath prefix
remove prefix from recorded source file paths
-v increase debug verbosity
-w debug type checking
-wb
enable write barrier (default true)

拓展阅读

https://stackoverflow.com/questions/70332316/whats-the-differenct-between-go-tool-compile-and-go-tool-objdump

https://xargin.com/plan9-assembly/

https://github.com/cch123/golang-notes/blob/master/assembly.md

欢迎关注我的其它发布渠道