【golang】不深入的虐一虐defer

 

原本想写一篇关于defer的常用和底层调用逻辑,然后发现其实自己目前还没能力。

推荐两篇文,再列一下自己的一些小demo & 执行结果 & 反汇编过程。

一、推荐的文章

煎鱼大佬的深入理解Go defer  https://eddycjy.com/posts/go/defer/2019-05-27-defer/

真迹大佬的 https://draveness.me/golang/docs/part2-foundation/ch05-keyword/golang-defer/

golang内存分配逃逸分析 https://driverzhang.github.io/post/golang%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E9%80%83%E9%80%B8%E5%88%86%E6%9E%90/

Golang 混合写屏障原理深入剖析 https://www.huaweicloud.com/articles/9aa423940e224bc6ff57a0c63e2615fa.html

Golang的垃圾回收与三色标记法 http://austsxk.com/2020/12/07/Golang-GC%20%E4%B8%89%E8%89%B2%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6%E4%B8%8E%E6%B7%B7%E5%90%88%E8%AF%BB%E5%86%99%E5%B1%8F%E9%9A%9C/

Golang三色标记、混合写屏障GC模式图文全分析 https://segmentfault.com/a/1190000022030353

Golang 内存管理 https://zhuanlan.zhihu.com/p/27807169

贴图来自:https://my.oschina.net/henrylee2cn/blog/505535 

贴图结论已验证

二、关于有名返回值和匿名返回值的Demo

func main()  {
	fmt.Println("a return:", a())
}
func a() (i int){

	defer func() {
		i++
		fmt.Println("a defer2:", i)
	}()
	defer func() {
		i++
		fmt.Println("a defer1:", i)
	}()

	return i
}

func main()  {
	fmt.Println("b return:", b())
}
func b() int {
	var i int
	defer func() {
		i++
		fmt.Println("b defer2", i)
	}()
	defer func() {
		i++
		fmt.Println("b defer1", i)

	}()
	return i
}
func main() {
	fmt.Println("c return:", c())
}

func c() (i int) {
	defer func() {
		i++
		fmt.Println("c defer2:", i)
	}()
	defer func() {
		i++
		fmt.Println("c defer1:", i)
	}()
	return 3
}

三、一些小demo

1、n次deferproc, >= n+1次deferreturn

func main()  {
	log.Println("main start \n")
	defer fmt.Println("defer ... ")
	log.Println("main end \n")
}

执行结果:

2021/02/08 11:44:37 main start

2021/02/08 11:44:37 main end

defer ...

反汇编

TEXT main.main(SB) .../main.go
  main.go:8             0x4cbbf0                65488b0c2528000000              MOVQ GS:0x28, CX
  main.go:8             0x4cbbf9                488b8900000000                  MOVQ 0(CX), CX
  main.go:8             0x4cbc00                488d842468ffffff                LEAQ 0xffffff68(SP), AX
  main.go:8             0x4cbc08                483b4110                        CMPQ 0x10(CX), AX
  main.go:8             0x4cbc0c                0f86e9010000                    JBE 0x4cbdfb
  main.go:8             0x4cbc12                4881ec18010000                  SUBQ $0x118, SP
  main.go:8             0x4cbc19                4889ac2410010000                MOVQ BP, 0x110(SP)
  main.go:8             0x4cbc21                488dac2410010000                LEAQ 0x110(SP), BP
  main.go:9             0x4cbc29                0f57c0                          XORPS X0, X0
  main.go:9             0x4cbc2c                0f118424b8000000                MOVUPS X0, 0xb8(SP)
  main.go:9             0x4cbc34                488d8424b8000000                LEAQ 0xb8(SP), AX
  main.go:9             0x4cbc3c                48898424a0000000                MOVQ AX, 0xa0(SP)
  main.go:9             0x4cbc44                8400                            TESTB AL, 0(AX)
  main.go:9             0x4cbc46                488d0df33c0100                  LEAQ type.*+80192(SB), CX
  main.go:9             0x4cbc4d                48898c24b8000000                MOVQ CX, 0xb8(SP)
  main.go:9             0x4cbc55                488d0da4d20400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+320(SB), CX
  main.go:9             0x4cbc5c                48898c24c0000000                MOVQ CX, 0xc0(SP)
  main.go:9             0x4cbc64                8400                            TESTB AL, 0(AX)
  main.go:9             0x4cbc66                eb00                            JMP 0x4cbc68
  main.go:9             0x4cbc68                48898424f8000000                MOVQ AX, 0xf8(SP)
  main.go:9             0x4cbc70                48c784240001000001000000        MOVQ $0x1, 0x100(SP)
  main.go:9             0x4cbc7c                48c784240801000001000000        MOVQ $0x1, 0x108(SP)
  main.go:9             0x4cbc88                48890424                        MOVQ AX, 0(SP)
  main.go:9             0x4cbc8c                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:9             0x4cbc95                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:9             0x4cbc9e                e81dfeffff                      CALL log.Println(SB)
  main.go:10            0x4cbca3                0f57c0                          XORPS X0, X0
  main.go:10            0x4cbca6                0f118424a8000000                MOVUPS X0, 0xa8(SP)
  main.go:10            0x4cbcae                488d8424a8000000                LEAQ 0xa8(SP), AX
  main.go:10            0x4cbcb6                4889842498000000                MOVQ AX, 0x98(SP)
  main.go:10            0x4cbcbe                8400                            TESTB AL, 0(AX)
  main.go:10            0x4cbcc0                488d0d793c0100                  LEAQ type.*+80192(SB), CX
  main.go:10            0x4cbcc7                48898c24a8000000                MOVQ CX, 0xa8(SP)
  main.go:10            0x4cbccf                488d0d3ad20400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+336(SB), CX
  main.go:10            0x4cbcd6                48898c24b0000000                MOVQ CX, 0xb0(SP)
  main.go:10            0x4cbcde                8400                            TESTB AL, 0(AX)
  main.go:10            0x4cbce0                eb00                            JMP 0x4cbce2
  main.go:10            0x4cbce2                48898424e0000000                MOVQ AX, 0xe0(SP)
  main.go:10            0x4cbcea                48c78424e800000001000000        MOVQ $0x1, 0xe8(SP)
  main.go:10            0x4cbcf6                48c78424f000000001000000        MOVQ $0x1, 0xf0(SP)
  main.go:10            0x4cbd02                c744243030000000                MOVL $0x30, 0x30(SP)
  main.go:10            0x4cbd0a                488d057f540400                  LEAQ go.func.*+15(SB), AX
  main.go:10            0x4cbd11                4889442448                      MOVQ AX, 0x48(SP)
  main.go:10            0x4cbd16                488b8424e8000000                MOVQ 0xe8(SP), AX
  main.go:10            0x4cbd1e                488b8c24e0000000                MOVQ 0xe0(SP), CX
  main.go:10            0x4cbd26                488b9424f0000000                MOVQ 0xf0(SP), DX
  main.go:10            0x4cbd2e                48894c2460                      MOVQ CX, 0x60(SP)
  main.go:10            0x4cbd33                4889442468                      MOVQ AX, 0x68(SP)
  main.go:10            0x4cbd38                4889542470                      MOVQ DX, 0x70(SP)
  main.go:10            0x4cbd3d                488d442430                      LEAQ 0x30(SP), AX
  main.go:10            0x4cbd42                48890424                        MOVQ AX, 0(SP)
  main.go:10            0x4cbd46                e8454cf6ff                      CALL runtime.deferprocStack(SB)
  main.go:10            0x4cbd4b                85c0                            TESTL AX, AX
  main.go:10            0x4cbd4d                0f8592000000                    JNE 0x4cbde5
  main.go:10            0x4cbd53                eb00                            JMP 0x4cbd55
  main.go:11            0x4cbd55                0f57c0                          XORPS X0, X0
  main.go:11            0x4cbd58                0f118424b8000000                MOVUPS X0, 0xb8(SP)
  main.go:11            0x4cbd60                488d8424b8000000                LEAQ 0xb8(SP), AX
  main.go:11            0x4cbd68                4889842490000000                MOVQ AX, 0x90(SP)
  main.go:11            0x4cbd70                8400                            TESTB AL, 0(AX)
  main.go:11            0x4cbd72                488d0dc73b0100                  LEAQ type.*+80192(SB), CX
  main.go:11            0x4cbd79                48898c24b8000000                MOVQ CX, 0xb8(SP)
  main.go:11            0x4cbd81                488d0d98d10400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+352(SB), CX
  main.go:11            0x4cbd88                48898c24c0000000                MOVQ CX, 0xc0(SP)
  main.go:11            0x4cbd90                8400                            TESTB AL, 0(AX)
  main.go:11            0x4cbd92                eb00                            JMP 0x4cbd94
  main.go:11            0x4cbd94                48898424c8000000                MOVQ AX, 0xc8(SP)
  main.go:11            0x4cbd9c                48c78424d000000001000000        MOVQ $0x1, 0xd0(SP)
  main.go:11            0x4cbda8                48c78424d800000001000000        MOVQ $0x1, 0xd8(SP)
  main.go:11            0x4cbdb4                48890424                        MOVQ AX, 0(SP)
  main.go:11            0x4cbdb8                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:11            0x4cbdc1                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:11            0x4cbdca                e8f1fcffff                      CALL log.Println(SB)
  main.go:12            0x4cbdcf                90                              NOPL
  main.go:12            0x4cbdd0                e8cb51f6ff                      CALL runtime.deferreturn(SB)
  main.go:12            0x4cbdd5                488bac2410010000                MOVQ 0x110(SP), BP
  main.go:12            0x4cbddd                4881c418010000                  ADDQ $0x118, SP
  main.go:12            0x4cbde4                c3                              RET
  main.go:10            0x4cbde5                90                              NOPL
  main.go:10            0x4cbde6                e8b551f6ff                      CALL runtime.deferreturn(SB)
  main.go:10            0x4cbdeb                488bac2410010000                MOVQ 0x110(SP), BP
  main.go:10            0x4cbdf3                4881c418010000                  ADDQ $0x118, SP
  main.go:10            0x4cbdfa                c3                              RET
  main.go:8             0x4cbdfb                e890ddf8ff                      CALL runtime.morestack_noctxt(SB)
  main.go:8             0x4cbe00                e9ebfdffff                      JMP main.main(SB)

摘取CALL

  main.go:9             0x4cbc9e                e81dfeffff                      CALL log.Println(SB)
  main.go:10            0x4cbd46                e8454cf6ff                      CALL runtime.deferprocStack(SB)
  main.go:11            0x4cbdca                e8f1fcffff                      CALL log.Println(SB)
  main.go:12            0x4cbdd0                e8cb51f6ff                      CALL runtime.deferreturn(SB)
  main.go:10            0x4cbde6                e8b551f6ff                      CALL runtime.deferreturn(SB)
  main.go:8             0x4cbdfb                e890ddf8ff                      CALL runtime.morestack_noctxt(SB)

2、

func main()  {
	log.Println("main start \n")
	defer func() {
		log.Printf("enter %s", "defer")

	}()
	log.Println("main end \n")
}

执行结果

2021/02/08 11:47:55 main start

2021/02/08 11:47:55 main end

2021/02/08 11:47:55 enter defer

反汇编

TEXT main.main(SB) .../main.go
  main.go:5             0x4cd900                65488b0c2528000000              MOVQ GS:0x28, CX
  main.go:5             0x4cd909                488b8900000000                  MOVQ 0(CX), CX
  main.go:5             0x4cd910                488d4424d8                      LEAQ -0x28(SP), AX
  main.go:5             0x4cd915                483b4110                        CMPQ 0x10(CX), AX
  main.go:5             0x4cd919                0f863b010000                    JBE 0x4cda5a
  main.go:5             0x4cd91f                4881eca8000000                  SUBQ $0xa8, SP
  main.go:5             0x4cd926                4889ac24a0000000                MOVQ BP, 0xa0(SP)
  main.go:5             0x4cd92e                488dac24a0000000                LEAQ 0xa0(SP), BP
  main.go:6             0x4cd936                0f57c0                          XORPS X0, X0
  main.go:6             0x4cd939                0f11442460                      MOVUPS X0, 0x60(SP)
  main.go:6             0x4cd93e                488d442460                      LEAQ 0x60(SP), AX
  main.go:6             0x4cd943                4889442458                      MOVQ AX, 0x58(SP)
  main.go:6             0x4cd948                8400                            TESTB AL, 0(AX)
  main.go:6             0x4cd94a                488d0def3f0100                  LEAQ type.*+80192(SB), CX
  main.go:6             0x4cd951                48894c2460                      MOVQ CX, 0x60(SP)
  main.go:6             0x4cd956                488d0d63d60400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+320(SB), CX
  main.go:6             0x4cd95d                48894c2468                      MOVQ CX, 0x68(SP)
  main.go:6             0x4cd962                8400                            TESTB AL, 0(AX)
  main.go:6             0x4cd964                eb00                            JMP 0x4cd966
  main.go:6             0x4cd966                4889842488000000                MOVQ AX, 0x88(SP)
  main.go:6             0x4cd96e                48c784249000000001000000        MOVQ $0x1, 0x90(SP)
  main.go:6             0x4cd97a                48c784249800000001000000        MOVQ $0x1, 0x98(SP)
  main.go:6             0x4cd986                48890424                        MOVQ AX, 0(SP)
  main.go:6             0x4cd98a                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:6             0x4cd993                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:6             0x4cd99c                e82ffeffff                      CALL log.Println(SB)
  main.go:7             0x4cd9a1                c744241800000000                MOVL $0x0, 0x18(SP)
  main.go:7             0x4cd9a9                488d05b0580400                  LEAQ go.func.*+159(SB), AX
  main.go:7             0x4cd9b0                4889442430                      MOVQ AX, 0x30(SP)
  main.go:7             0x4cd9b5                488d442418                      LEAQ 0x18(SP), AX
  main.go:7             0x4cd9ba                48890424                        MOVQ AX, 0(SP)
  main.go:7             0x4cd9be                e8cd2ff6ff                      CALL runtime.deferprocStack(SB)
  main.go:7             0x4cd9c3                85c0                            TESTL AX, AX
  main.go:7             0x4cd9c5                757d                            JNE 0x4cda44
  main.go:7             0x4cd9c7                eb00                            JMP 0x4cd9c9
  main.go:11            0x4cd9c9                0f57c0                          XORPS X0, X0
  main.go:11            0x4cd9cc                0f11442460                      MOVUPS X0, 0x60(SP)
  main.go:11            0x4cd9d1                488d442460                      LEAQ 0x60(SP), AX
  main.go:11            0x4cd9d6                4889442450                      MOVQ AX, 0x50(SP)
  main.go:11            0x4cd9db                8400                            TESTB AL, 0(AX)
  main.go:11            0x4cd9dd                488d0d5c3f0100                  LEAQ type.*+80192(SB), CX
  main.go:11            0x4cd9e4                48894c2460                      MOVQ CX, 0x60(SP)
  main.go:11            0x4cd9e9                488d0de0d50400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+336(SB), CX
  main.go:11            0x4cd9f0                48894c2468                      MOVQ CX, 0x68(SP)
  main.go:11            0x4cd9f5                8400                            TESTB AL, 0(AX)
  main.go:11            0x4cd9f7                eb00                            JMP 0x4cd9f9
  main.go:11            0x4cd9f9                4889442470                      MOVQ AX, 0x70(SP)
  main.go:11            0x4cd9fe                48c744247801000000              MOVQ $0x1, 0x78(SP)
  main.go:11            0x4cda07                48c784248000000001000000        MOVQ $0x1, 0x80(SP)
  main.go:11            0x4cda13                48890424                        MOVQ AX, 0(SP)
  main.go:11            0x4cda17                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:11            0x4cda20                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:11            0x4cda29                e8a2fdffff                      CALL log.Println(SB)
  main.go:12            0x4cda2e                90                              NOPL
  main.go:12            0x4cda2f                e86c35f6ff                      CALL runtime.deferreturn(SB)
  main.go:12            0x4cda34                488bac24a0000000                MOVQ 0xa0(SP), BP
  main.go:12            0x4cda3c                4881c4a8000000                  ADDQ $0xa8, SP
  main.go:12            0x4cda43                c3                              RET
  main.go:7             0x4cda44                90                              NOPL
  main.go:7             0x4cda45                e85635f6ff                      CALL runtime.deferreturn(SB)
  main.go:7             0x4cda4a                488bac24a0000000                MOVQ 0xa0(SP), BP
  main.go:7             0x4cda52                4881c4a8000000                  ADDQ $0xa8, SP
  main.go:7             0x4cda59                c3                              RET
  main.go:5             0x4cda5a                e831c1f8ff                      CALL runtime.morestack_noctxt(SB)
  main.go:5             0x4cda5f                e99cfeffff                      JMP main.main(SB)
  :-1                   0x4cda64                cc                              INT $0x3
  :-1                   0x4cda65                cc                              INT $0x3
  :-1                   0x4cda66                cc                              INT $0x3
  :-1                   0x4cda67                cc                              INT $0x3
  :-1                   0x4cda68                cc                              INT $0x3
  :-1                   0x4cda69                cc                              INT $0x3
  :-1                   0x4cda6a                cc                              INT $0x3
  :-1                   0x4cda6b                cc                              INT $0x3
  :-1                   0x4cda6c                cc                              INT $0x3
  :-1                   0x4cda6d                cc                              INT $0x3
  :-1                   0x4cda6e                cc                              INT $0x3
  :-1                   0x4cda6f                cc                              INT $0x3

TEXT main.main.func1(SB) .../main.go
  main.go:7             0x4cda70                65488b0c2528000000      MOVQ GS:0x28, CX
  main.go:7             0x4cda79                488b8900000000          MOVQ 0(CX), CX
  main.go:7             0x4cda80                483b6110                CMPQ 0x10(CX), SP
  main.go:7             0x4cda84                0f8694000000            JBE 0x4cdb1e
  main.go:7             0x4cda8a                4883ec60                SUBQ $0x60, SP
  main.go:7             0x4cda8e                48896c2458              MOVQ BP, 0x58(SP)
  main.go:7             0x4cda93                488d6c2458              LEAQ 0x58(SP), BP
  main.go:8             0x4cda98                0f57c0                  XORPS X0, X0
  main.go:8             0x4cda9b                0f11442430              MOVUPS X0, 0x30(SP)
  main.go:8             0x4cdaa0                488d442430              LEAQ 0x30(SP), AX
  main.go:8             0x4cdaa5                4889442428              MOVQ AX, 0x28(SP)
  main.go:8             0x4cdaaa                8400                    TESTB AL, 0(AX)
  main.go:8             0x4cdaac                488d0d8d3e0100          LEAQ type.*+80192(SB), CX
  main.go:8             0x4cdab3                48894c2430              MOVQ CX, 0x30(SP)
  main.go:8             0x4cdab8                488d0d21d50400          LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+352(SB), CX
  main.go:8             0x4cdabf                48894c2438              MOVQ CX, 0x38(SP)
  main.go:8             0x4cdac4                8400                    TESTB AL, 0(AX)
  main.go:8             0x4cdac6                eb00                    JMP 0x4cdac8
  main.go:8             0x4cdac8                4889442440              MOVQ AX, 0x40(SP)
  main.go:8             0x4cdacd                48c744244801000000      MOVQ $0x1, 0x48(SP)
  main.go:8             0x4cdad6                48c744245001000000      MOVQ $0x1, 0x50(SP)
  main.go:8             0x4cdadf                488d05a3cd0300          LEAQ go.string.*+2441(SB), AX
  main.go:8             0x4cdae6                48890424                MOVQ AX, 0(SP)
  main.go:8             0x4cdaea                48c744240808000000      MOVQ $0x8, 0x8(SP)
  main.go:8             0x4cdaf3                488b442440              MOVQ 0x40(SP), AX
  main.go:8             0x4cdaf8                4889442410              MOVQ AX, 0x10(SP)
  main.go:8             0x4cdafd                48c744241801000000      MOVQ $0x1, 0x18(SP)
  main.go:8             0x4cdb06                48c744242001000000      MOVQ $0x1, 0x20(SP)
  main.go:8             0x4cdb0f                e80cfcffff              CALL log.Printf(SB)
  main.go:10            0x4cdb14                488b6c2458              MOVQ 0x58(SP), BP
  main.go:10            0x4cdb19                4883c460                ADDQ $0x60, SP
  main.go:10            0x4cdb1d                c3                      RET
  main.go:7             0x4cdb1e                e86dc0f8ff              CALL runtime.morestack_noctxt(SB)
  main.go:7             0x4cdb23                e948ffffff              JMP main.main.func1(SB)

摘取CALL

  main.go:6             0x4cd99c                e82ffeffff                      CALL log.Println(SB)
  main.go:7             0x4cd9be                e8cd2ff6ff                      CALL runtime.deferprocStack(SB)
  main.go:11            0x4cda29                e8a2fdffff                      CALL log.Println(SB)
  main.go:12            0x4cda2f                e86c35f6ff                      CALL runtime.deferreturn(SB)
  main.go:7             0x4cda45                e85635f6ff                      CALL runtime.deferreturn(SB)
  main.go:5             0x4cda5a                e831c1f8ff                      CALL runtime.morestack_noctxt(SB)

###############################下面是 func1 的 CALL
  main.go:8             0x4cdb0f                e80cfcffff              CALL log.Printf(SB)
  main.go:7             0x4cdb1e                e86dc0f8ff              CALL runtime.morestack_noctxt(SB)

3、

func main()  {
	log.Println("main start \n")
	defer func (msg string) func() {
		start := time.Now()
		log.Printf("enter %s", msg)
		return func() {
			log.Printf("exit %s (%s)", msg, time.Since(start)) //闭包引发逃逸,堆上对象赋值,触发垃圾回收机制
		}
	}("defer")()
	log.Println("main end \n")
}

执行结果

2021/02/08 11:56:45 main start

2021/02/08 11:56:45 enter defer
2021/02/08 11:56:45 main end

2021/02/08 11:56:45 exit defer (0s)

反汇编

TEXT main.main(SB) .../main.go
  main.go:8             0x4cecb0                65488b0c2528000000              MOVQ GS:0x28, CX
  main.go:8             0x4cecb9                488b8900000000                  MOVQ 0(CX), CX
  main.go:8             0x4cecc0                488d4424d0                      LEAQ -0x30(SP), AX
  main.go:8             0x4cecc5                483b4110                        CMPQ 0x10(CX), AX
  main.go:8             0x4cecc9                0f865e010000                    JBE 0x4cee2d
  main.go:8             0x4ceccf                4881ecb0000000                  SUBQ $0xb0, SP
  main.go:8             0x4cecd6                4889ac24a8000000                MOVQ BP, 0xa8(SP)
  main.go:8             0x4cecde                488dac24a8000000                LEAQ 0xa8(SP), BP
  main.go:9             0x4cece6                0f57c0                          XORPS X0, X0
  main.go:9             0x4cece9                0f11442468                      MOVUPS X0, 0x68(SP)
  main.go:9             0x4cecee                488d442468                      LEAQ 0x68(SP), AX
  main.go:9             0x4cecf3                4889442458                      MOVQ AX, 0x58(SP)
  main.go:9             0x4cecf8                8400                            TESTB AL, 0(AX)
  main.go:9             0x4cecfa                488d0d5f4d0100                  LEAQ runtime.rodata+80480(SB), CX
  main.go:9             0x4ced01                48894c2468                      MOVQ CX, 0x68(SP)
  main.go:9             0x4ced06                488d0d73e70400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+320(SB), CX
  main.go:9             0x4ced0d                48894c2470                      MOVQ CX, 0x70(SP)
  main.go:9             0x4ced12                8400                            TESTB AL, 0(AX)
  main.go:9             0x4ced14                eb00                            JMP 0x4ced16
  main.go:9             0x4ced16                4889842490000000                MOVQ AX, 0x90(SP)
  main.go:9             0x4ced1e                48c784249800000001000000        MOVQ $0x1, 0x98(SP)
  main.go:9             0x4ced2a                48c78424a000000001000000        MOVQ $0x1, 0xa0(SP)
  main.go:9             0x4ced36                48890424                        MOVQ AX, 0(SP)
  main.go:9             0x4ced3a                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:9             0x4ced43                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:9             0x4ced4c                e82ffeffff                      CALL log.Println(SB)
  main.go:16            0x4ced51                488d057bd90300                  LEAQ go.string.*+1011(SB), AX
  main.go:16            0x4ced58                48890424                        MOVQ AX, 0(SP)
  main.go:16            0x4ced5c                48c744240805000000              MOVQ $0x5, 0x8(SP)
  main.go:16            0x4ced65                e876020000                      CALL main.main.func1(SB)
  main.go:16            0x4ced6a                488b442410                      MOVQ 0x10(SP), AX
  main.go:16            0x4ced6f                4889442460                      MOVQ AX, 0x60(SP)
  main.go:10            0x4ced74                c744241800000000                MOVL $0x0, 0x18(SP)
  main.go:10            0x4ced7c                4889442430                      MOVQ AX, 0x30(SP)
  main.go:10            0x4ced81                488d442418                      LEAQ 0x18(SP), AX
  main.go:10            0x4ced86                48890424                        MOVQ AX, 0(SP)
  main.go:10            0x4ced8a                e8011cf6ff                      CALL runtime.deferprocStack(SB)
  main.go:10            0x4ced8f                85c0                            TESTL AX, AX
  main.go:10            0x4ced91                0f8580000000                    JNE 0x4cee17
  main.go:10            0x4ced97                eb00                            JMP 0x4ced99
  main.go:17            0x4ced99                0f57c0                          XORPS X0, X0
  main.go:17            0x4ced9c                0f11442468                      MOVUPS X0, 0x68(SP)
  main.go:17            0x4ceda1                488d442468                      LEAQ 0x68(SP), AX
  main.go:17            0x4ceda6                4889442450                      MOVQ AX, 0x50(SP)
  main.go:17            0x4cedab                8400                            TESTB AL, 0(AX)
  main.go:17            0x4cedad                488d0dac4c0100                  LEAQ runtime.rodata+80480(SB), CX
  main.go:17            0x4cedb4                48894c2468                      MOVQ CX, 0x68(SP)
  main.go:17            0x4cedb9                488d0dd0e60400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+336(SB), CX
  main.go:17            0x4cedc0                48894c2470                      MOVQ CX, 0x70(SP)
  main.go:17            0x4cedc5                8400                            TESTB AL, 0(AX)
  main.go:17            0x4cedc7                eb00                            JMP 0x4cedc9
  main.go:17            0x4cedc9                4889442478                      MOVQ AX, 0x78(SP)
  main.go:17            0x4cedce                48c784248000000001000000        MOVQ $0x1, 0x80(SP)
  main.go:17            0x4cedda                48c784248800000001000000        MOVQ $0x1, 0x88(SP)
  main.go:17            0x4cede6                48890424                        MOVQ AX, 0(SP)
  main.go:17            0x4cedea                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:17            0x4cedf3                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:17            0x4cedfc                e87ffdffff                      CALL log.Println(SB)
  main.go:18            0x4cee01                90                              NOPL
  main.go:18            0x4cee02                e89921f6ff                      CALL runtime.deferreturn(SB)
  main.go:18            0x4cee07                488bac24a8000000                MOVQ 0xa8(SP), BP
  main.go:18            0x4cee0f                4881c4b0000000                  ADDQ $0xb0, SP
  main.go:18            0x4cee16                c3                              RET
  main.go:10            0x4cee17                90                              NOPL
  main.go:10            0x4cee18                e88321f6ff                      CALL runtime.deferreturn(SB)
  main.go:10            0x4cee1d                488bac24a8000000                MOVQ 0xa8(SP), BP
  main.go:10            0x4cee25                4881c4b0000000                  ADDQ $0xb0, SP
  main.go:10            0x4cee2c                c3                              RET
  main.go:8             0x4cee2d                e85eadf8ff                      CALL runtime.morestack_noctxt(SB)
  main.go:8             0x4cee32                e979feffff                      JMP main.main(SB)
  :-1                   0x4cee37                cc                              INT $0x3
  :-1                   0x4cee38                cc                              INT $0x3
  :-1                   0x4cee39                cc                              INT $0x3
  :-1                   0x4cee3a                cc                              INT $0x3
  :-1                   0x4cee3b                cc                              INT $0x3
  :-1                   0x4cee3c                cc                              INT $0x3
  :-1                   0x4cee3d                cc                              INT $0x3
  :-1                   0x4cee3e                cc                              INT $0x3
  :-1                   0x4cee3f                cc                              INT $0x3

TEXT main.main.func1.1(SB) .../main.go
  main.go:13            0x4cee40                65488b0c2528000000      MOVQ GS:0x28, CX
  main.go:13            0x4cee49                488b8900000000          MOVQ 0(CX), CX
  main.go:13            0x4cee50                488d4424c8              LEAQ -0x38(SP), AX
  main.go:13            0x4cee55                483b4110                CMPQ 0x10(CX), AX
  main.go:13            0x4cee59                0f866e010000            JBE 0x4cefcd
  main.go:13            0x4cee5f                4881ecb8000000          SUBQ $0xb8, SP
  main.go:13            0x4cee66                4889ac24b0000000        MOVQ BP, 0xb0(SP)
  main.go:13            0x4cee6e                488dac24b0000000        LEAQ 0xb0(SP), BP
  main.go:13            0x4cee76                488b4208                MOVQ 0x8(DX), AX
  main.go:13            0x4cee7a                488b4a10                MOVQ 0x10(DX), CX
  main.go:13            0x4cee7e                4889442450              MOVQ AX, 0x50(SP)
  main.go:13            0x4cee83                48894c2458              MOVQ CX, 0x58(SP)
  main.go:13            0x4cee88                488d4218                LEAQ 0x18(DX), AX
  main.go:13            0x4cee8c                4889442448              MOVQ AX, 0x48(SP)
  main.go:14            0x4cee91                488b4220                MOVQ 0x20(DX), AX
  main.go:14            0x4cee95                488b4a18                MOVQ 0x18(DX), CX
  main.go:14            0x4cee99                488b5228                MOVQ 0x28(DX), DX
  main.go:14            0x4cee9d                48894c2478              MOVQ CX, 0x78(SP)
  main.go:14            0x4ceea2                4889842480000000        MOVQ AX, 0x80(SP)
  main.go:14            0x4ceeaa                4889942488000000        MOVQ DX, 0x88(SP)
  main.go:14            0x4ceeb2                48890c24                MOVQ CX, 0(SP)
  main.go:14            0x4ceeb6                4889442408              MOVQ AX, 0x8(SP)
  main.go:14            0x4ceebb                4889542410              MOVQ DX, 0x10(SP)
  main.go:14            0x4ceec0                e8cb56feff              CALL time.Since(SB)
  main.go:14            0x4ceec5                488b442418              MOVQ 0x18(SP), AX
  main.go:14            0x4ceeca                4889442428              MOVQ AX, 0x28(SP)
  main.go:14            0x4ceecf                488b442458              MOVQ 0x58(SP), AX
  main.go:14            0x4ceed4                488b4c2450              MOVQ 0x50(SP), CX
  main.go:14            0x4ceed9                48890c24                MOVQ CX, 0(SP)
  main.go:14            0x4ceedd                4889442408              MOVQ AX, 0x8(SP)
  main.go:14            0x4ceee2                e829b1f3ff              CALL runtime.convTstring(SB)
  main.go:14            0x4ceee7                488b442410              MOVQ 0x10(SP), AX
  main.go:14            0x4ceeec                4889442440              MOVQ AX, 0x40(SP)
  main.go:14            0x4ceef1                488b442428              MOVQ 0x28(SP), AX
  main.go:14            0x4ceef6                48890424                MOVQ AX, 0(SP)
  main.go:14            0x4ceefa                e891b0f3ff              CALL runtime.convT64(SB)
  main.go:14            0x4ceeff                488b442408              MOVQ 0x8(SP), AX
  main.go:14            0x4cef04                4889442438              MOVQ AX, 0x38(SP)
  main.go:14            0x4cef09                0f57c0                  XORPS X0, X0
  main.go:14            0x4cef0c                0f11842490000000        MOVUPS X0, 0x90(SP)
  main.go:14            0x4cef14                0f57c0                  XORPS X0, X0
  main.go:14            0x4cef17                0f118424a0000000        MOVUPS X0, 0xa0(SP)
  main.go:14            0x4cef1f                488d842490000000        LEAQ 0x90(SP), AX
  main.go:14            0x4cef27                4889442430              MOVQ AX, 0x30(SP)
  main.go:14            0x4cef2c                8400                    TESTB AL, 0(AX)
  main.go:14            0x4cef2e                488b4c2440              MOVQ 0x40(SP), CX
  main.go:14            0x4cef33                488d15264b0100          LEAQ runtime.rodata+80480(SB), DX
  main.go:14            0x4cef3a                4889942490000000        MOVQ DX, 0x90(SP)
  main.go:14            0x4cef42                48898c2498000000        MOVQ CX, 0x98(SP)
  main.go:14            0x4cef4a                8400                    TESTB AL, 0(AX)
  main.go:14            0x4cef4c                488b442438              MOVQ 0x38(SP), AX
  main.go:14            0x4cef51                488d0da8c50200          LEAQ runtime.rodata+177408(SB), CX
  main.go:14            0x4cef58                48898c24a0000000        MOVQ CX, 0xa0(SP)
  main.go:14            0x4cef60                48898424a8000000        MOVQ AX, 0xa8(SP)
  main.go:14            0x4cef68                488b442430              MOVQ 0x30(SP), AX
  main.go:14            0x4cef6d                8400                    TESTB AL, 0(AX)
  main.go:14            0x4cef6f                eb00                    JMP 0x4cef71
  main.go:14            0x4cef71                4889442460              MOVQ AX, 0x60(SP)
  main.go:14            0x4cef76                48c744246802000000      MOVQ $0x2, 0x68(SP)
  main.go:14            0x4cef7f                48c744247002000000      MOVQ $0x2, 0x70(SP)
  main.go:14            0x4cef88                488d057ae80300          LEAQ go.string.*+5417(SB), AX
  main.go:14            0x4cef8f                48890424                MOVQ AX, 0(SP)
  main.go:14            0x4cef93                48c74424080c000000      MOVQ $0xc, 0x8(SP)
  main.go:14            0x4cef9c                488b442460              MOVQ 0x60(SP), AX
  main.go:14            0x4cefa1                4889442410              MOVQ AX, 0x10(SP)
  main.go:14            0x4cefa6                48c744241802000000      MOVQ $0x2, 0x18(SP)
  main.go:14            0x4cefaf                48c744242002000000      MOVQ $0x2, 0x20(SP)
  main.go:14            0x4cefb8                e813fbffff              CALL log.Printf(SB)
  main.go:15            0x4cefbd                488bac24b0000000        MOVQ 0xb0(SP), BP
  main.go:15            0x4cefc5                4881c4b8000000          ADDQ $0xb8, SP
  main.go:15            0x4cefcc                c3                      RET
  main.go:13            0x4cefcd                e81eabf8ff              CALL runtime.morestack(SB)
  main.go:13            0x4cefd2                e969feffff              JMP main.main.func1.1(SB)
  :-1                   0x4cefd7                cc                      INT $0x3
  :-1                   0x4cefd8                cc                      INT $0x3
  :-1                   0x4cefd9                cc                      INT $0x3
  :-1                   0x4cefda                cc                      INT $0x3
  :-1                   0x4cefdb                cc                      INT $0x3
  :-1                   0x4cefdc                cc                      INT $0x3
  :-1                   0x4cefdd                cc                      INT $0x3
  :-1                   0x4cefde                cc                      INT $0x3
  :-1                   0x4cefdf                cc                      INT $0x3

TEXT main.main.func1(SB) .../main.go
  main.go:10            0x4cefe0                65488b0c2528000000              MOVQ GS:0x28, CX
  main.go:10            0x4cefe9                488b8900000000                  MOVQ 0(CX), CX
  main.go:10            0x4ceff0                488d4424f8                      LEAQ -0x8(SP), AX
  main.go:10            0x4ceff5                483b4110                        CMPQ 0x10(CX), AX
  main.go:10            0x4ceff9                0f869c010000                    JBE 0x4cf19b
  main.go:10            0x4cefff                4881ec88000000                  SUBQ $0x88, SP
  main.go:10            0x4cf006                4889ac2480000000                MOVQ BP, 0x80(SP)
  main.go:10            0x4cf00e                488dac2480000000                LEAQ 0x80(SP), BP
  main.go:10            0x4cf016                48c78424a000000000000000        MOVQ $0x0, 0xa0(SP)
  main.go:11            0x4cf022                e8e95bfeff                      CALL time.Now(SB)
  main.go:11            0x4cf027                488b0424                        MOVQ 0(SP), AX
  main.go:11            0x4cf02b                488b4c2408                      MOVQ 0x8(SP), CX
  main.go:11            0x4cf030                488b542410                      MOVQ 0x10(SP), DX
  main.go:11            0x4cf035                4889442450                      MOVQ AX, 0x50(SP)
  main.go:11            0x4cf03a                48894c2458                      MOVQ CX, 0x58(SP)
  main.go:11            0x4cf03f                4889542460                      MOVQ DX, 0x60(SP)
  main.go:12            0x4cf044                488b842490000000                MOVQ 0x90(SP), AX
  main.go:12            0x4cf04c                488b8c2498000000                MOVQ 0x98(SP), CX
  main.go:12            0x4cf054                48890424                        MOVQ AX, 0(SP)
  main.go:12            0x4cf058                48894c2408                      MOVQ CX, 0x8(SP)
  main.go:12            0x4cf05d                e8aeaff3ff                      CALL runtime.convTstring(SB)
  main.go:12            0x4cf062                488b442410                      MOVQ 0x10(SP), AX
  main.go:12            0x4cf067                4889442438                      MOVQ AX, 0x38(SP)
  main.go:12            0x4cf06c                0f57c0                          XORPS X0, X0
  main.go:12            0x4cf06f                0f11442440                      MOVUPS X0, 0x40(SP)
  main.go:12            0x4cf074                488d442440                      LEAQ 0x40(SP), AX
  main.go:12            0x4cf079                4889442430                      MOVQ AX, 0x30(SP)
  main.go:12            0x4cf07e                8400                            TESTB AL, 0(AX)
  main.go:12            0x4cf080                488b4c2438                      MOVQ 0x38(SP), CX
  main.go:12            0x4cf085                488d15d4490100                  LEAQ runtime.rodata+80480(SB), DX
  main.go:12            0x4cf08c                4889542440                      MOVQ DX, 0x40(SP)
  main.go:12            0x4cf091                48894c2448                      MOVQ CX, 0x48(SP)
  main.go:12            0x4cf096                8400                            TESTB AL, 0(AX)
  main.go:12            0x4cf098                eb00                            JMP 0x4cf09a
  main.go:12            0x4cf09a                4889442468                      MOVQ AX, 0x68(SP)
  main.go:12            0x4cf09f                48c744247001000000              MOVQ $0x1, 0x70(SP)
  main.go:12            0x4cf0a8                48c744247801000000              MOVQ $0x1, 0x78(SP)
  main.go:12            0x4cf0b1                488d05b5db0300                  LEAQ go.string.*+2445(SB), AX
  main.go:12            0x4cf0b8                48890424                        MOVQ AX, 0(SP)
  main.go:12            0x4cf0bc                48c744240808000000              MOVQ $0x8, 0x8(SP)
  main.go:12            0x4cf0c5                488b442468                      MOVQ 0x68(SP), AX
  main.go:12            0x4cf0ca                4889442410                      MOVQ AX, 0x10(SP)
  main.go:12            0x4cf0cf                48c744241801000000              MOVQ $0x1, 0x18(SP)
  main.go:12            0x4cf0d8                48c744242001000000              MOVQ $0x1, 0x20(SP)
  main.go:12            0x4cf0e1                e8eaf9ffff                      CALL log.Printf(SB)
  main.go:13            0x4cf0e6                488d05f3590200                  LEAQ runtime.rodata+150240(SB), AX
  main.go:13            0x4cf0ed                48890424                        MOVQ AX, 0(SP)
  main.go:13            0x4cf0f1                e87adaf3ff                      CALL runtime.newobject(SB) //闭包引用对象逃逸
  main.go:13            0x4cf0f6                488b442408                      MOVQ 0x8(SP), AX
  main.go:13            0x4cf0fb                4889442428                      MOVQ AX, 0x28(SP)
  main.go:13            0x4cf100                488d0d39fdffff                  LEAQ 0xfffffd39(IP), CX
  main.go:13            0x4cf107                488908                          MOVQ CX, 0(AX)
  main.go:13            0x4cf10a                488b442428                      MOVQ 0x28(SP), AX
  main.go:13            0x4cf10f                8400                            TESTB AL, 0(AX)
  main.go:13            0x4cf111                488b8c2498000000                MOVQ 0x98(SP), CX
  main.go:13            0x4cf119                488b942490000000                MOVQ 0x90(SP), DX
  main.go:13            0x4cf121                48894810                        MOVQ CX, 0x10(AX)
  main.go:13            0x4cf125                488d7808                        LEAQ 0x8(AX), DI
  main.go:13            0x4cf129                833db08e100000                  CMPL $0x0, runtime.writeBarrier(SB) //堆上对象赋值触发写屏蔽,runtime.writeBarrier是一个包含写屏障状态的结构体,其中的 enabled 字段表示写屏障的开启与关闭;
  main.go:13            0x4cf130                7402                            JE 0x4cf134
  main.go:13            0x4cf132                eb5d                            JMP 0x4cf191
  main.go:13            0x4cf134                48895008                        MOVQ DX, 0x8(AX)
  main.go:13            0x4cf138                eb00                            JMP 0x4cf13a
  main.go:13            0x4cf13a                488b4c2428                      MOVQ 0x28(SP), CX
  main.go:13            0x4cf13f                8401                            TESTB AL, 0(CX)
  main.go:13            0x4cf141                488b542450                      MOVQ 0x50(SP), DX
  main.go:13            0x4cf146                488b5c2458                      MOVQ 0x58(SP), BX
  main.go:13            0x4cf14b                488b442460                      MOVQ 0x60(SP), AX
  main.go:13            0x4cf150                48895118                        MOVQ DX, 0x18(CX)
  main.go:13            0x4cf154                48895920                        MOVQ BX, 0x20(CX)
  main.go:13            0x4cf158                488d7928                        LEAQ 0x28(CX), DI
  main.go:13            0x4cf15c                833d7d8e100000                  CMPL $0x0, runtime.writeBarrier(SB)//堆上对象赋值触发写屏蔽,runtime.writeBarrier是一个包含写屏障状态的结构体,其中的 enabled 字段表示写屏障的开启与关闭;
  main.go:13            0x4cf163                7402                            JE 0x4cf167
  main.go:13            0x4cf165                eb23                            JMP 0x4cf18a
  main.go:13            0x4cf167                48894128                        MOVQ AX, 0x28(CX)
  main.go:13            0x4cf16b                eb00                            JMP 0x4cf16d
  main.go:13            0x4cf16d                488b442428                      MOVQ 0x28(SP), AX
  main.go:13            0x4cf172                48898424a0000000                MOVQ AX, 0xa0(SP)
  main.go:13            0x4cf17a                488bac2480000000                MOVQ 0x80(SP), BP
  main.go:13            0x4cf182                4881c488000000                  ADDQ $0x88, SP
  main.go:13            0x4cf189                c3                              RET
  main.go:13            0x4cf18a                e8f1c9f8ff                      CALL runtime.gcWriteBarrier(SB) //执行写请求,处理gc相关逻辑
  main.go:13            0x4cf18f                ebdc                            JMP 0x4cf16d
  main.go:13            0x4cf191                4889d0                          MOVQ DX, AX
  main.go:13            0x4cf194                e8e7c9f8ff                      CALL runtime.gcWriteBarrier(SB) //执行写请求,处理gc相关逻辑
  main.go:13            0x4cf199                eb9f                            JMP 0x4cf13a
  main.go:10            0x4cf19b                e8f0a9f8ff                      CALL runtime.morestack_noctxt(SB)
  main.go:10            0x4cf1a0                e93bfeffff                      JMP main.main.func1(SB)
  :-1                   0x4cf1a5                cc                              INT $0x3
  :-1                   0x4cf1a6                cc                              INT $0x3
  :-1                   0x4cf1a7                cc                              INT $0x3
  :-1                   0x4cf1a8                cc                              INT $0x3
  :-1                   0x4cf1a9                cc                              INT $0x3
  :-1                   0x4cf1aa                cc                              INT $0x3
  :-1                   0x4cf1ab                cc                              INT $0x3
  :-1                   0x4cf1ac                cc                              INT $0x3
  :-1                   0x4cf1ad                cc                              INT $0x3
  :-1                   0x4cf1ae                cc                              INT $0x3
  :-1                   0x4cf1af                cc                              INT $0x3

提取CALL

  main.go:9             0x4ced4c                e82ffeffff                      CALL log.Println(SB)
  main.go:16            0x4ced65                e876020000                      CALL main.main.func1(SB)
  main.go:10            0x4ced8a                e8011cf6ff                      CALL runtime.deferprocStack(SB)
  main.go:17            0x4cedfc                e87ffdffff                      CALL log.Println(SB)
  main.go:18            0x4cee02                e89921f6ff                      CALL runtime.deferreturn(SB)
  main.go:10            0x4cee18                e88321f6ff                      CALL runtime.deferreturn(SB)
  main.go:8             0x4cee2d                e85eadf8ff                      CALL runtime.morestack_noctxt(SB)

############################下面是 func1.1 的 CALL
  main.go:14            0x4ceec0                e8cb56feff              CALL time.Since(SB)
  main.go:14            0x4ceee2                e829b1f3ff              CALL runtime.convTstring(SB)
  main.go:14            0x4ceefa                e891b0f3ff              CALL runtime.convT64(SB)
  main.go:14            0x4cefb8                e813fbffff              CALL log.Printf(SB)
  main.go:13            0x4cefcd                e81eabf8ff              CALL runtime.morestack(SB)

###########################下面是 func1 的 CALL
  main.go:11            0x4cf022                e8e95bfeff                      CALL time.Now(SB)
  main.go:12            0x4cf05d                e8aeaff3ff                      CALL runtime.convTstring(SB)
  main.go:12            0x4cf0e1                e8eaf9ffff                      CALL log.Printf(SB)
  main.go:13            0x4cf0f1                e87adaf3ff                      CALL runtime.newobject(SB)
  main.go:13            0x4cf18a                e8f1c9f8ff                      CALL runtime.gcWriteBarrier(SB)
  main.go:13            0x4cf194                e8e7c9f8ff                      CALL runtime.gcWriteBarrier(SB)
  main.go:10            0x4cf19b                e8f0a9f8ff                      CALL runtime.morestack_noctxt(SB)

4、

func main()  {
	log.Println("main start \n")
	defer func (msg string) func() {
		start := time.Now()
		log.Printf("enter %s", msg)
		return func(msg string, start time.Time) func() {
			log.Printf("enter %s (%s)", msg, time.Since(start))
			return func() {
				log.Println("start to exit...")
			}
		}("second defer", start)
	}("first defer")()
	log.Println("main end \n")
}

执行结果

2021/02/08 12:05:06 main start

2021/02/08 12:05:06 enter first defer
2021/02/08 12:05:06 enter second defer (0s)
2021/02/08 12:05:06 main end

2021/02/08 12:05:06 start to exit...

反汇编

TEXT main.main(SB) .../main.go
  main.go:8             0x4cecb0                65488b0c2528000000              MOVQ GS:0x28, CX
  main.go:8             0x4cecb9                488b8900000000                  MOVQ 0(CX), CX
  main.go:8             0x4cecc0                488d4424d0                      LEAQ -0x30(SP), AX
  main.go:8             0x4cecc5                483b4110                        CMPQ 0x10(CX), AX
  main.go:8             0x4cecc9                0f865e010000                    JBE 0x4cee2d
  main.go:8             0x4ceccf                4881ecb0000000                  SUBQ $0xb0, SP
  main.go:8             0x4cecd6                4889ac24a8000000                MOVQ BP, 0xa8(SP)
  main.go:8             0x4cecde                488dac24a8000000                LEAQ 0xa8(SP), BP
  main.go:9             0x4cece6                0f57c0                          XORPS X0, X0
  main.go:9             0x4cece9                0f11442468                      MOVUPS X0, 0x68(SP)
  main.go:9             0x4cecee                488d442468                      LEAQ 0x68(SP), AX
  main.go:9             0x4cecf3                4889442458                      MOVQ AX, 0x58(SP)
  main.go:9             0x4cecf8                8400                            TESTB AL, 0(AX)
  main.go:9             0x4cecfa                488d0ddf4c0100                  LEAQ runtime.types+80352(SB), CX
  main.go:9             0x4ced01                48894c2468                      MOVQ CX, 0x68(SP)
  main.go:9             0x4ced06                488d0d93e60400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+320(SB), CX
  main.go:9             0x4ced0d                48894c2470                      MOVQ CX, 0x70(SP)
  main.go:9             0x4ced12                8400                            TESTB AL, 0(AX)
  main.go:9             0x4ced14                eb00                            JMP 0x4ced16
  main.go:9             0x4ced16                4889842490000000                MOVQ AX, 0x90(SP)
  main.go:9             0x4ced1e                48c784249800000001000000        MOVQ $0x1, 0x98(SP)
  main.go:9             0x4ced2a                48c78424a000000001000000        MOVQ $0x1, 0xa0(SP)
  main.go:9             0x4ced36                48890424                        MOVQ AX, 0(SP)
  main.go:9             0x4ced3a                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:9             0x4ced43                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:9             0x4ced4c                e82ffeffff                      CALL log.Println(SB)
  main.go:19            0x4ced51                488d051ce60300                  LEAQ go.string.*+4532(SB), AX
  main.go:19            0x4ced58                48890424                        MOVQ AX, 0(SP)
  main.go:19            0x4ced5c                48c74424080b000000              MOVQ $0xb, 0x8(SP)
  main.go:19            0x4ced65                e8f6020000                      CALL main.main.func1(SB)
  main.go:19            0x4ced6a                488b442410                      MOVQ 0x10(SP), AX
  main.go:19            0x4ced6f                4889442460                      MOVQ AX, 0x60(SP)
  main.go:10            0x4ced74                c744241800000000                MOVL $0x0, 0x18(SP)
  main.go:10            0x4ced7c                4889442430                      MOVQ AX, 0x30(SP)
  main.go:10            0x4ced81                488d442418                      LEAQ 0x18(SP), AX
  main.go:10            0x4ced86                48890424                        MOVQ AX, 0(SP)
  main.go:10            0x4ced8a                e8011cf6ff                      CALL runtime.deferprocStack(SB)
  main.go:10            0x4ced8f                85c0                            TESTL AX, AX
  main.go:10            0x4ced91                0f8580000000                    JNE 0x4cee17
  main.go:10            0x4ced97                eb00                            JMP 0x4ced99
  main.go:20            0x4ced99                0f57c0                          XORPS X0, X0
  main.go:20            0x4ced9c                0f11442468                      MOVUPS X0, 0x68(SP)
  main.go:20            0x4ceda1                488d442468                      LEAQ 0x68(SP), AX
  main.go:20            0x4ceda6                4889442450                      MOVQ AX, 0x50(SP)
  main.go:20            0x4cedab                8400                            TESTB AL, 0(AX)
  main.go:20            0x4cedad                488d0d2c4c0100                  LEAQ runtime.types+80352(SB), CX
  main.go:20            0x4cedb4                48894c2468                      MOVQ CX, 0x68(SP)
  main.go:20            0x4cedb9                488d0df0e50400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+336(SB), CX
  main.go:20            0x4cedc0                48894c2470                      MOVQ CX, 0x70(SP)
  main.go:20            0x4cedc5                8400                            TESTB AL, 0(AX)
  main.go:20            0x4cedc7                eb00                            JMP 0x4cedc9
  main.go:20            0x4cedc9                4889442478                      MOVQ AX, 0x78(SP)
  main.go:20            0x4cedce                48c784248000000001000000        MOVQ $0x1, 0x80(SP)
  main.go:20            0x4cedda                48c784248800000001000000        MOVQ $0x1, 0x88(SP)
  main.go:20            0x4cede6                48890424                        MOVQ AX, 0(SP)
  main.go:20            0x4cedea                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:20            0x4cedf3                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:20            0x4cedfc                e87ffdffff                      CALL log.Println(SB)
  main.go:21            0x4cee01                90                              NOPL
  main.go:21            0x4cee02                e89921f6ff                      CALL runtime.deferreturn(SB)
  main.go:21            0x4cee07                488bac24a8000000                MOVQ 0xa8(SP), BP
  main.go:21            0x4cee0f                4881c4b0000000                  ADDQ $0xb0, SP
  main.go:21            0x4cee16                c3                              RET
  main.go:10            0x4cee17                90                              NOPL
  main.go:10            0x4cee18                e88321f6ff                      CALL runtime.deferreturn(SB)
  main.go:10            0x4cee1d                488bac24a8000000                MOVQ 0xa8(SP), BP
  main.go:10            0x4cee25                4881c4b0000000                  ADDQ $0xb0, SP
  main.go:10            0x4cee2c                c3                              RET
  main.go:8             0x4cee2d                e85eadf8ff                      CALL runtime.morestack_noctxt(SB)
  main.go:8             0x4cee32                e979feffff                      JMP main.main(SB)
  :-1                   0x4cee37                cc                              INT $0x3
  :-1                   0x4cee38                cc                              INT $0x3
  :-1                   0x4cee39                cc                              INT $0x3
  :-1                   0x4cee3a                cc                              INT $0x3
  :-1                   0x4cee3b                cc                              INT $0x3
  :-1                   0x4cee3c                cc                              INT $0x3
  :-1                   0x4cee3d                cc                              INT $0x3
  :-1                   0x4cee3e                cc                              INT $0x3
  :-1                   0x4cee3f                cc                              INT $0x3

TEXT main.main.func1.1.1(SB) .../main.go
  main.go:15            0x4cee40                65488b0c2528000000      MOVQ GS:0x28, CX
  main.go:15            0x4cee49                488b8900000000          MOVQ 0(CX), CX
  main.go:15            0x4cee50                483b6110                CMPQ 0x10(CX), SP
  main.go:15            0x4cee54                767a                    JBE 0x4ceed0
  main.go:15            0x4cee56                4883ec50                SUBQ $0x50, SP
  main.go:15            0x4cee5a                48896c2448              MOVQ BP, 0x48(SP)
  main.go:15            0x4cee5f                488d6c2448              LEAQ 0x48(SP), BP
  main.go:16            0x4cee64                0f57c0                  XORPS X0, X0
  main.go:16            0x4cee67                0f11442420              MOVUPS X0, 0x20(SP)
  main.go:16            0x4cee6c                488d442420              LEAQ 0x20(SP), AX
  main.go:16            0x4cee71                4889442418              MOVQ AX, 0x18(SP)
  main.go:16            0x4cee76                8400                    TESTB AL, 0(AX)
  main.go:16            0x4cee78                488d0d614b0100          LEAQ runtime.types+80352(SB), CX
  main.go:16            0x4cee7f                48894c2420              MOVQ CX, 0x20(SP)
  main.go:16            0x4cee84                488d0d35e50400          LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+352(SB), CX
  main.go:16            0x4cee8b                48894c2428              MOVQ CX, 0x28(SP)
  main.go:16            0x4cee90                8400                    TESTB AL, 0(AX)
  main.go:16            0x4cee92                eb00                    JMP 0x4cee94
  main.go:16            0x4cee94                4889442430              MOVQ AX, 0x30(SP)
  main.go:16            0x4cee99                48c744243801000000      MOVQ $0x1, 0x38(SP)
  main.go:16            0x4ceea2                48c744244001000000      MOVQ $0x1, 0x40(SP)
  main.go:16            0x4ceeab                48890424                MOVQ AX, 0(SP)
  main.go:16            0x4ceeaf                48c744240801000000      MOVQ $0x1, 0x8(SP)
  main.go:16            0x4ceeb8                48c744241001000000      MOVQ $0x1, 0x10(SP)
  main.go:16            0x4ceec1                e8bafcffff              CALL log.Println(SB)
  main.go:17            0x4ceec6                488b6c2448              MOVQ 0x48(SP), BP
  main.go:17            0x4ceecb                4883c450                ADDQ $0x50, SP
  main.go:17            0x4ceecf                c3                      RET
  main.go:15            0x4ceed0                e8bbacf8ff              CALL runtime.morestack_noctxt(SB)
  main.go:15            0x4ceed5                e966ffffff              JMP main.main.func1.1.1(SB)
  :-1                   0x4ceeda                cc                      INT $0x3
  :-1                   0x4ceedb                cc                      INT $0x3
  :-1                   0x4ceedc                cc                      INT $0x3
  :-1                   0x4ceedd                cc                      INT $0x3
  :-1                   0x4ceede                cc                      INT $0x3
  :-1                   0x4ceedf                cc                      INT $0x3

TEXT main.main.func1.1(SB) .../main.go
  main.go:13            0x4ceee0                65488b0c2528000000              MOVQ GS:0x28, CX
  main.go:13            0x4ceee9                488b8900000000                  MOVQ 0(CX), CX
  main.go:13            0x4ceef0                488d4424f8                      LEAQ -0x8(SP), AX
  main.go:13            0x4ceef5                483b4110                        CMPQ 0x10(CX), AX
  main.go:13            0x4ceef9                0f8656010000                    JBE 0x4cf055
  main.go:13            0x4ceeff                4881ec88000000                  SUBQ $0x88, SP
  main.go:13            0x4cef06                4889ac2480000000                MOVQ BP, 0x80(SP)
  main.go:13            0x4cef0e                488dac2480000000                LEAQ 0x80(SP), BP
  main.go:13            0x4cef16                48c78424b800000000000000        MOVQ $0x0, 0xb8(SP)
  main.go:14            0x4cef22                488b8424a8000000                MOVQ 0xa8(SP), AX
  main.go:14            0x4cef2a                488b8c24a0000000                MOVQ 0xa0(SP), CX
  main.go:14            0x4cef32                488b9424b0000000                MOVQ 0xb0(SP), DX
  main.go:14            0x4cef3a                48890c24                        MOVQ CX, 0(SP)
  main.go:14            0x4cef3e                4889442408                      MOVQ AX, 0x8(SP)
  main.go:14            0x4cef43                4889542410                      MOVQ DX, 0x10(SP)
  main.go:14            0x4cef48                e84356feff                      CALL time.Since(SB)
  main.go:14            0x4cef4d                488b442418                      MOVQ 0x18(SP), AX
  main.go:14            0x4cef52                4889442428                      MOVQ AX, 0x28(SP)
  main.go:14            0x4cef57                488b842490000000                MOVQ 0x90(SP), AX
  main.go:14            0x4cef5f                488b8c2498000000                MOVQ 0x98(SP), CX
  main.go:14            0x4cef67                48890424                        MOVQ AX, 0(SP)
  main.go:14            0x4cef6b                48894c2408                      MOVQ CX, 0x8(SP)
  main.go:14            0x4cef70                e89bb0f3ff                      CALL runtime.convTstring(SB)
  main.go:14            0x4cef75                488b442410                      MOVQ 0x10(SP), AX
  main.go:14            0x4cef7a                4889442440                      MOVQ AX, 0x40(SP)
  main.go:14            0x4cef7f                488b442428                      MOVQ 0x28(SP), AX
  main.go:14            0x4cef84                48890424                        MOVQ AX, 0(SP)
  main.go:14            0x4cef88                e803b0f3ff                      CALL runtime.convT64(SB)
  main.go:14            0x4cef8d                488b442408                      MOVQ 0x8(SP), AX
  main.go:14            0x4cef92                4889442438                      MOVQ AX, 0x38(SP)
  main.go:14            0x4cef97                0f57c0                          XORPS X0, X0
  main.go:14            0x4cef9a                0f11442460                      MOVUPS X0, 0x60(SP)
  main.go:14            0x4cef9f                0f57c0                          XORPS X0, X0
  main.go:14            0x4cefa2                0f11442470                      MOVUPS X0, 0x70(SP)
  main.go:14            0x4cefa7                488d442460                      LEAQ 0x60(SP), AX
  main.go:14            0x4cefac                4889442430                      MOVQ AX, 0x30(SP)
  main.go:14            0x4cefb1                8400                            TESTB AL, 0(AX)
  main.go:14            0x4cefb3                488b4c2440                      MOVQ 0x40(SP), CX
  main.go:14            0x4cefb8                488d15214a0100                  LEAQ runtime.types+80352(SB), DX
  main.go:14            0x4cefbf                4889542460                      MOVQ DX, 0x60(SP)
  main.go:14            0x4cefc4                48894c2468                      MOVQ CX, 0x68(SP)
  main.go:14            0x4cefc9                8400                            TESTB AL, 0(AX)
  main.go:14            0x4cefcb                488b442438                      MOVQ 0x38(SP), AX
  main.go:14            0x4cefd0                488d0d09c40200                  LEAQ runtime.types+177120(SB), CX
  main.go:14            0x4cefd7                48894c2470                      MOVQ CX, 0x70(SP)
  main.go:14            0x4cefdc                4889442478                      MOVQ AX, 0x78(SP)
  main.go:14            0x4cefe1                488b442430                      MOVQ 0x30(SP), AX
  main.go:14            0x4cefe6                8400                            TESTB AL, 0(AX)
  main.go:14            0x4cefe8                eb00                            JMP 0x4cefea
  main.go:14            0x4cefea                4889442448                      MOVQ AX, 0x48(SP)
  main.go:14            0x4cefef                48c744245002000000              MOVQ $0x2, 0x50(SP)
  main.go:14            0x4ceff8                48c744245802000000              MOVQ $0x2, 0x58(SP)
  main.go:14            0x4cf001                488d05c5e90300                  LEAQ go.string.*+6157(SB), AX
  main.go:14            0x4cf008                48890424                        MOVQ AX, 0(SP)
  main.go:14            0x4cf00c                48c74424080d000000              MOVQ $0xd, 0x8(SP)
  main.go:14            0x4cf015                488b442448                      MOVQ 0x48(SP), AX
  main.go:14            0x4cf01a                4889442410                      MOVQ AX, 0x10(SP)
  main.go:14            0x4cf01f                48c744241802000000              MOVQ $0x2, 0x18(SP)
  main.go:14            0x4cf028                48c744242002000000              MOVQ $0x2, 0x20(SP)
  main.go:14            0x4cf031                e89afaffff                      CALL log.Printf(SB)
  main.go:15            0x4cf036                488d0513650400                  LEAQ go.func.*+156(SB), AX
  main.go:15            0x4cf03d                48898424b8000000                MOVQ AX, 0xb8(SP)
  main.go:15            0x4cf045                488bac2480000000                MOVQ 0x80(SP), BP
  main.go:15            0x4cf04d                4881c488000000                  ADDQ $0x88, SP
  main.go:15            0x4cf054                c3                              RET
  main.go:13            0x4cf055                e836abf8ff                      CALL runtime.morestack_noctxt(SB)
  main.go:13            0x4cf05a                e981feffff                      JMP main.main.func1.1(SB)
  :-1                   0x4cf05f                cc                              INT $0x3

TEXT main.main.func1(SB) .../main.go
  main.go:10            0x4cf060                65488b0c2528000000              MOVQ GS:0x28, CX
  main.go:10            0x4cf069                488b8900000000                  MOVQ 0(CX), CX
  main.go:10            0x4cf070                488d4424f0                      LEAQ -0x10(SP), AX
  main.go:10            0x4cf075                483b4110                        CMPQ 0x10(CX), AX
  main.go:10            0x4cf079                0f8643010000                    JBE 0x4cf1c2
  main.go:10            0x4cf07f                4881ec90000000                  SUBQ $0x90, SP
  main.go:10            0x4cf086                4889ac2488000000                MOVQ BP, 0x88(SP)
  main.go:10            0x4cf08e                488dac2488000000                LEAQ 0x88(SP), BP
  main.go:10            0x4cf096                48c78424a800000000000000        MOVQ $0x0, 0xa8(SP)
  main.go:11            0x4cf0a2                e8695bfeff                      CALL time.Now(SB)
  main.go:11            0x4cf0a7                488b442408                      MOVQ 0x8(SP), AX
  main.go:11            0x4cf0ac                488b0c24                        MOVQ 0(SP), CX
  main.go:11            0x4cf0b0                488b542410                      MOVQ 0x10(SP), DX
  main.go:11            0x4cf0b5                48894c2458                      MOVQ CX, 0x58(SP)
  main.go:11            0x4cf0ba                4889442460                      MOVQ AX, 0x60(SP)
  main.go:11            0x4cf0bf                4889542468                      MOVQ DX, 0x68(SP)
  main.go:12            0x4cf0c4                488b842498000000                MOVQ 0x98(SP), AX
  main.go:12            0x4cf0cc                488b8c24a0000000                MOVQ 0xa0(SP), CX
  main.go:12            0x4cf0d4                48890424                        MOVQ AX, 0(SP)
  main.go:12            0x4cf0d8                48894c2408                      MOVQ CX, 0x8(SP)
  main.go:12            0x4cf0dd                e82eaff3ff                      CALL runtime.convTstring(SB)
  main.go:12            0x4cf0e2                488b442410                      MOVQ 0x10(SP), AX
  main.go:12            0x4cf0e7                4889442438                      MOVQ AX, 0x38(SP)
  main.go:12            0x4cf0ec                0f57c0                          XORPS X0, X0
  main.go:12            0x4cf0ef                0f11442448                      MOVUPS X0, 0x48(SP)
  main.go:12            0x4cf0f4                488d442448                      LEAQ 0x48(SP), AX
  main.go:12            0x4cf0f9                4889442430                      MOVQ AX, 0x30(SP)
  main.go:12            0x4cf0fe                8400                            TESTB AL, 0(AX)
  main.go:12            0x4cf100                488b4c2438                      MOVQ 0x38(SP), CX
  main.go:12            0x4cf105                488d15d4480100                  LEAQ runtime.types+80352(SB), DX
  main.go:12            0x4cf10c                4889542448                      MOVQ DX, 0x48(SP)
  main.go:12            0x4cf111                48894c2450                      MOVQ CX, 0x50(SP)
  main.go:12            0x4cf116                8400                            TESTB AL, 0(AX)
  main.go:12            0x4cf118                eb00                            JMP 0x4cf11a
  main.go:12            0x4cf11a                4889442470                      MOVQ AX, 0x70(SP)
  main.go:12            0x4cf11f                48c744247801000000              MOVQ $0x1, 0x78(SP)
  main.go:12            0x4cf128                48c784248000000001000000        MOVQ $0x1, 0x80(SP)
  main.go:12            0x4cf134                488d050dda0300                  LEAQ go.string.*+2440(SB), AX
  main.go:12            0x4cf13b                48890424                        MOVQ AX, 0(SP)
  main.go:12            0x4cf13f                48c744240808000000              MOVQ $0x8, 0x8(SP)
  main.go:12            0x4cf148                488b442470                      MOVQ 0x70(SP), AX
  main.go:12            0x4cf14d                4889442410                      MOVQ AX, 0x10(SP)
  main.go:12            0x4cf152                48c744241801000000              MOVQ $0x1, 0x18(SP)
  main.go:12            0x4cf15b                48c744242001000000              MOVQ $0x1, 0x20(SP)
  main.go:12            0x4cf164                e867f9ffff                      CALL log.Printf(SB)
  main.go:18            0x4cf169                488d0533e60300                  LEAQ go.string.*+5603(SB), AX
  main.go:18            0x4cf170                48890424                        MOVQ AX, 0(SP)
  main.go:18            0x4cf174                48c74424080c000000              MOVQ $0xc, 0x8(SP)
  main.go:18            0x4cf17d                488b442458                      MOVQ 0x58(SP), AX
  main.go:18            0x4cf182                488b4c2460                      MOVQ 0x60(SP), CX
  main.go:18            0x4cf187                488b542468                      MOVQ 0x68(SP), DX
  main.go:18            0x4cf18c                4889442410                      MOVQ AX, 0x10(SP)
  main.go:18            0x4cf191                48894c2418                      MOVQ CX, 0x18(SP)
  main.go:18            0x4cf196                4889542420                      MOVQ DX, 0x20(SP)
  main.go:18            0x4cf19b                e840fdffff                      CALL main.main.func1.1(SB)
  main.go:18            0x4cf1a0                488b442428                      MOVQ 0x28(SP), AX
  main.go:18            0x4cf1a5                4889442440                      MOVQ AX, 0x40(SP)
  main.go:13            0x4cf1aa                48898424a8000000                MOVQ AX, 0xa8(SP)
  main.go:13            0x4cf1b2                488bac2488000000                MOVQ 0x88(SP), BP
  main.go:13            0x4cf1ba                4881c490000000                  ADDQ $0x90, SP
  main.go:13            0x4cf1c1                c3                              RET
  main.go:10            0x4cf1c2                e8c9a9f8ff                      CALL runtime.morestack_noctxt(SB)
  main.go:10            0x4cf1c7                e994feffff                      JMP main.main.func1(SB)
  :-1                   0x4cf1cc                cc                              INT $0x3
  :-1                   0x4cf1cd                cc                              INT $0x3
  :-1                   0x4cf1ce                cc                              INT $0x3
  :-1                   0x4cf1cf                cc                              INT $0x3

提取CALL

  main.go:9             0x4ced4c                e82ffeffff                      CALL log.Println(SB)
  main.go:19            0x4ced65                e8f6020000                      CALL main.main.func1(SB)
  main.go:10            0x4ced8a                e8011cf6ff                      CALL runtime.deferprocStack(SB)
  main.go:20            0x4cedfc                e87ffdffff                      CALL log.Println(SB)
  main.go:21            0x4cee02                e89921f6ff                      CALL runtime.deferreturn(SB)
  main.go:10            0x4cee18                e88321f6ff                      CALL runtime.deferreturn(SB)
  main.go:8             0x4cee2d                e85eadf8ff                      CALL runtime.morestack_noctxt(SB)

#####################下面是 func1.1.1 的 CALL
  main.go:16            0x4ceec1                e8bafcffff              CALL log.Println(SB)
  main.go:15            0x4ceed0                e8bbacf8ff              CALL runtime.morestack_noctxt(SB)
#####################下面是 func1.1 的 CALL
  main.go:14            0x4cef48                e84356feff                      CALL time.Since(SB)
  main.go:14            0x4cef70                e89bb0f3ff                      CALL runtime.convTstring(SB)
  main.go:14            0x4cef88                e803b0f3ff                      CALL runtime.convT64(SB)
  main.go:14            0x4cf031                e89afaffff                      CALL log.Printf(SB)
  main.go:13            0x4cf055                e836abf8ff                      CALL runtime.morestack_noctxt(SB)
#####################下面是 func1 的 CALL
  main.go:11            0x4cf0a2                e8695bfeff                      CALL time.Now(SB)
  main.go:12            0x4cf0dd                e82eaff3ff                      CALL runtime.convTstring(SB)
  main.go:12            0x4cf164                e867f9ffff                      CALL log.Printf(SB)
  main.go:18            0x4cf19b                e840fdffff                      CALL main.main.func1.1(SB)
  main.go:10            0x4cf1c2                e8c9a9f8ff                      CALL runtime.morestack_noctxt(SB)

5、

func main()  {
	log.Println("main start \n")
	defer func() {
		log.Println("this is first defer")
		defer func() {
			log.Println("this is the defer of the first defer")
		}()
	}()
	log.Println("second defer start \n")
	defer func() {
		log.Println("this is second defer")
	}()
	log.Println("main end \n")
}

执行结果

2021/02/08 12:10:10 main start

2021/02/08 12:10:10 second defer start

2021/02/08 12:10:10 main end

2021/02/08 12:10:10 this is second defer
2021/02/08 12:10:10 this is first defer
2021/02/08 12:10:10 this is the defer of the first defer

反汇编

TEXT main.main(SB) .../main.go
  main.go:5             0x4cb9a0                65488b0c2528000000              MOVQ GS:0x28, CX
  main.go:5             0x4cb9a9                488b8900000000                  MOVQ 0(CX), CX
  main.go:5             0x4cb9b0                488d442480                      LEAQ -0x80(SP), AX
  main.go:5             0x4cb9b5                483b4110                        CMPQ 0x10(CX), AX
  main.go:5             0x4cb9b9                0f861f020000                    JBE 0x4cbbde
  main.go:5             0x4cb9bf                4881ec00010000                  SUBQ $0x100, SP
  main.go:5             0x4cb9c6                4889ac24f8000000                MOVQ BP, 0xf8(SP)
  main.go:5             0x4cb9ce                488dac24f8000000                LEAQ 0xf8(SP), BP
  main.go:6             0x4cb9d6                0f57c0                          XORPS X0, X0
  main.go:6             0x4cb9d9                0f118424a0000000                MOVUPS X0, 0xa0(SP)
  main.go:6             0x4cb9e1                488d8424a0000000                LEAQ 0xa0(SP), AX
  main.go:6             0x4cb9e9                4889842498000000                MOVQ AX, 0x98(SP)
  main.go:6             0x4cb9f1                8400                            TESTB AL, 0(AX)
  main.go:6             0x4cb9f3                488d0d463f0100                  LEAQ runtime.rodata+80192(SB), CX
  main.go:6             0x4cb9fa                48898c24a0000000                MOVQ CX, 0xa0(SP)
  main.go:6             0x4cba02                488d0d17d50400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+320(SB), CX
  main.go:6             0x4cba09                48898c24a8000000                MOVQ CX, 0xa8(SP)
  main.go:6             0x4cba11                8400                            TESTB AL, 0(AX)
  main.go:6             0x4cba13                eb00                            JMP 0x4cba15
  main.go:6             0x4cba15                48898424e0000000                MOVQ AX, 0xe0(SP)
  main.go:6             0x4cba1d                48c78424e800000001000000        MOVQ $0x1, 0xe8(SP)
  main.go:6             0x4cba29                48c78424f000000001000000        MOVQ $0x1, 0xf0(SP)
  main.go:6             0x4cba35                48890424                        MOVQ AX, 0(SP)
  main.go:6             0x4cba39                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:6             0x4cba42                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:6             0x4cba4b                e820feffff                      CALL log.Println(SB)
  main.go:7             0x4cba50                c744241800000000                MOVL $0x0, 0x18(SP)
  main.go:7             0x4cba58                488d0519580400                  LEAQ go.func.*+162(SB), AX
  main.go:7             0x4cba5f                4889442430                      MOVQ AX, 0x30(SP)
  main.go:7             0x4cba64                488d442418                      LEAQ 0x18(SP), AX
  main.go:7             0x4cba69                48890424                        MOVQ AX, 0(SP)
  main.go:7             0x4cba6d                e81e4ff6ff                      CALL runtime.deferprocStack(SB)
  main.go:7             0x4cba72                85c0                            TESTL AX, AX
  main.go:7             0x4cba74                0f854e010000                    JNE 0x4cbbc8
  main.go:7             0x4cba7a                eb00                            JMP 0x4cba7c
  main.go:13            0x4cba7c                0f57c0                          XORPS X0, X0
  main.go:13            0x4cba7f                0f118424a0000000                MOVUPS X0, 0xa0(SP)
  main.go:13            0x4cba87                488d8424a0000000                LEAQ 0xa0(SP), AX
  main.go:13            0x4cba8f                4889842490000000                MOVQ AX, 0x90(SP)
  main.go:13            0x4cba97                8400                            TESTB AL, 0(AX)
  main.go:13            0x4cba99                488d0da03e0100                  LEAQ runtime.rodata+80192(SB), CX
  main.go:13            0x4cbaa0                48898c24a0000000                MOVQ CX, 0xa0(SP)
  main.go:13            0x4cbaa8                488d0d81d40400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+336(SB), CX
  main.go:13            0x4cbaaf                48898c24a8000000                MOVQ CX, 0xa8(SP)
  main.go:13            0x4cbab7                8400                            TESTB AL, 0(AX)
  main.go:13            0x4cbab9                eb00                            JMP 0x4cbabb
  main.go:13            0x4cbabb                48898424c8000000                MOVQ AX, 0xc8(SP)
  main.go:13            0x4cbac3                48c78424d000000001000000        MOVQ $0x1, 0xd0(SP)
  main.go:13            0x4cbacf                48c78424d800000001000000        MOVQ $0x1, 0xd8(SP)
  main.go:13            0x4cbadb                48890424                        MOVQ AX, 0(SP)
  main.go:13            0x4cbadf                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:13            0x4cbae8                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:13            0x4cbaf1                e87afdffff                      CALL log.Println(SB)
  main.go:14            0x4cbaf6                c744245000000000                MOVL $0x0, 0x50(SP)
  main.go:14            0x4cbafe                488d057b570400                  LEAQ go.func.*+170(SB), AX
  main.go:14            0x4cbb05                4889442468                      MOVQ AX, 0x68(SP)
  main.go:14            0x4cbb0a                488d442450                      LEAQ 0x50(SP), AX
  main.go:14            0x4cbb0f                48890424                        MOVQ AX, 0(SP)
  main.go:14            0x4cbb13                e8784ef6ff                      CALL runtime.deferprocStack(SB)
  main.go:14            0x4cbb18                85c0                            TESTL AX, AX
  main.go:14            0x4cbb1a                0f8592000000                    JNE 0x4cbbb2
  main.go:14            0x4cbb20                eb00                            JMP 0x4cbb22
  main.go:17            0x4cbb22                0f57c0                          XORPS X0, X0
  main.go:17            0x4cbb25                0f118424a0000000                MOVUPS X0, 0xa0(SP)
  main.go:17            0x4cbb2d                488d8424a0000000                LEAQ 0xa0(SP), AX
  main.go:17            0x4cbb35                4889842488000000                MOVQ AX, 0x88(SP)
  main.go:17            0x4cbb3d                8400                            TESTB AL, 0(AX)
  main.go:17            0x4cbb3f                488d0dfa3d0100                  LEAQ runtime.rodata+80192(SB), CX
  main.go:17            0x4cbb46                48898c24a0000000                MOVQ CX, 0xa0(SP)
  main.go:17            0x4cbb4e                488d0debd30400                  LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+352(SB), CX
  main.go:17            0x4cbb55                48898c24a8000000                MOVQ CX, 0xa8(SP)
  main.go:17            0x4cbb5d                8400                            TESTB AL, 0(AX)
  main.go:17            0x4cbb5f                eb00                            JMP 0x4cbb61
  main.go:17            0x4cbb61                48898424b0000000                MOVQ AX, 0xb0(SP)
  main.go:17            0x4cbb69                48c78424b800000001000000        MOVQ $0x1, 0xb8(SP)
  main.go:17            0x4cbb75                48c78424c000000001000000        MOVQ $0x1, 0xc0(SP)
  main.go:17            0x4cbb81                48890424                        MOVQ AX, 0(SP)
  main.go:17            0x4cbb85                48c744240801000000              MOVQ $0x1, 0x8(SP)
  main.go:17            0x4cbb8e                48c744241001000000              MOVQ $0x1, 0x10(SP)
  main.go:17            0x4cbb97                e8d4fcffff                      CALL log.Println(SB)
  main.go:18            0x4cbb9c                90                              NOPL
  main.go:18            0x4cbb9d                e8fe53f6ff                      CALL runtime.deferreturn(SB)
  main.go:18            0x4cbba2                488bac24f8000000                MOVQ 0xf8(SP), BP
  main.go:18            0x4cbbaa                4881c400010000                  ADDQ $0x100, SP
  main.go:18            0x4cbbb1                c3                              RET
  main.go:14            0x4cbbb2                90                              NOPL
  main.go:14            0x4cbbb3                e8e853f6ff                      CALL runtime.deferreturn(SB)
  main.go:14            0x4cbbb8                488bac24f8000000                MOVQ 0xf8(SP), BP
  main.go:14            0x4cbbc0                4881c400010000                  ADDQ $0x100, SP
  main.go:14            0x4cbbc7                c3                              RET
  main.go:7             0x4cbbc8                90                              NOPL
  main.go:7             0x4cbbc9                e8d253f6ff                      CALL runtime.deferreturn(SB)
  main.go:7             0x4cbbce                488bac24f8000000                MOVQ 0xf8(SP), BP
  main.go:7             0x4cbbd6                4881c400010000                  ADDQ $0x100, SP
  main.go:7             0x4cbbdd                c3                              RET
  main.go:5             0x4cbbde                e8addff8ff                      CALL runtime.morestack_noctxt(SB)
  main.go:5             0x4cbbe3                e9b8fdffff                      JMP main.main(SB)
  :-1                   0x4cbbe8                cc                              INT $0x3
  :-1                   0x4cbbe9                cc                              INT $0x3
  :-1                   0x4cbbea                cc                              INT $0x3
  :-1                   0x4cbbeb                cc                              INT $0x3
  :-1                   0x4cbbec                cc                              INT $0x3
  :-1                   0x4cbbed                cc                              INT $0x3
  :-1                   0x4cbbee                cc                              INT $0x3
  :-1                   0x4cbbef                cc                              INT $0x3

TEXT main.main.func1.1(SB) .../main.go
  main.go:9             0x4cbbf0                65488b0c2528000000      MOVQ GS:0x28, CX
  main.go:9             0x4cbbf9                488b8900000000          MOVQ 0(CX), CX
  main.go:9             0x4cbc00                483b6110                CMPQ 0x10(CX), SP
  main.go:9             0x4cbc04                767a                    JBE 0x4cbc80
  main.go:9             0x4cbc06                4883ec50                SUBQ $0x50, SP
  main.go:9             0x4cbc0a                48896c2448              MOVQ BP, 0x48(SP)
  main.go:9             0x4cbc0f                488d6c2448              LEAQ 0x48(SP), BP
  main.go:10            0x4cbc14                0f57c0                  XORPS X0, X0
  main.go:10            0x4cbc17                0f11442420              MOVUPS X0, 0x20(SP)
  main.go:10            0x4cbc1c                488d442420              LEAQ 0x20(SP), AX
  main.go:10            0x4cbc21                4889442418              MOVQ AX, 0x18(SP)
  main.go:10            0x4cbc26                8400                    TESTB AL, 0(AX)
  main.go:10            0x4cbc28                488d0d113d0100          LEAQ runtime.rodata+80192(SB), CX
  main.go:10            0x4cbc2f                48894c2420              MOVQ CX, 0x20(SP)
  main.go:10            0x4cbc34                488d0d15d30400          LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+368(SB), CX
  main.go:10            0x4cbc3b                48894c2428              MOVQ CX, 0x28(SP)
  main.go:10            0x4cbc40                8400                    TESTB AL, 0(AX)
  main.go:10            0x4cbc42                eb00                    JMP 0x4cbc44
  main.go:10            0x4cbc44                4889442430              MOVQ AX, 0x30(SP)
  main.go:10            0x4cbc49                48c744243801000000      MOVQ $0x1, 0x38(SP)
  main.go:10            0x4cbc52                48c744244001000000      MOVQ $0x1, 0x40(SP)
  main.go:10            0x4cbc5b                48890424                MOVQ AX, 0(SP)
  main.go:10            0x4cbc5f                48c744240801000000      MOVQ $0x1, 0x8(SP)
  main.go:10            0x4cbc68                48c744241001000000      MOVQ $0x1, 0x10(SP)
  main.go:10            0x4cbc71                e8fafbffff              CALL log.Println(SB)
  main.go:11            0x4cbc76                488b6c2448              MOVQ 0x48(SP), BP
  main.go:11            0x4cbc7b                4883c450                ADDQ $0x50, SP
  main.go:11            0x4cbc7f                c3                      RET
  main.go:9             0x4cbc80                e80bdff8ff              CALL runtime.morestack_noctxt(SB)
  main.go:9             0x4cbc85                e966ffffff              JMP main.main.func1.1(SB)
  :-1                   0x4cbc8a                cc                      INT $0x3
  :-1                   0x4cbc8b                cc                      INT $0x3
  :-1                   0x4cbc8c                cc                      INT $0x3
  :-1                   0x4cbc8d                cc                      INT $0x3
  :-1                   0x4cbc8e                cc                      INT $0x3
  :-1                   0x4cbc8f                cc                      INT $0x3

TEXT main.main.func1(SB) .../main.go
  main.go:7             0x4cbc90                65488b0c2528000000      MOVQ GS:0x28, CX
  main.go:7             0x4cbc99                488b8900000000          MOVQ 0(CX), CX
  main.go:7             0x4cbca0                488d4424f8              LEAQ -0x8(SP), AX
  main.go:7             0x4cbca5                483b4110                CMPQ 0x10(CX), AX
  main.go:7             0x4cbca9                0f86cd000000            JBE 0x4cbd7c
  main.go:7             0x4cbcaf                4881ec88000000          SUBQ $0x88, SP
  main.go:7             0x4cbcb6                4889ac2480000000        MOVQ BP, 0x80(SP)
  main.go:7             0x4cbcbe                488dac2480000000        LEAQ 0x80(SP), BP
  main.go:8             0x4cbcc6                0f57c0                  XORPS X0, X0
  main.go:8             0x4cbcc9                0f11442458              MOVUPS X0, 0x58(SP)
  main.go:8             0x4cbcce                488d442458              LEAQ 0x58(SP), AX
  main.go:8             0x4cbcd3                4889442450              MOVQ AX, 0x50(SP)
  main.go:8             0x4cbcd8                8400                    TESTB AL, 0(AX)
  main.go:8             0x4cbcda                488d0d5f3c0100          LEAQ runtime.rodata+80192(SB), CX
  main.go:8             0x4cbce1                48894c2458              MOVQ CX, 0x58(SP)
  main.go:8             0x4cbce6                488d0d73d20400          LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+384(SB), CX
  main.go:8             0x4cbced                48894c2460              MOVQ CX, 0x60(SP)
  main.go:8             0x4cbcf2                8400                    TESTB AL, 0(AX)
  main.go:8             0x4cbcf4                eb00                    JMP 0x4cbcf6
  main.go:8             0x4cbcf6                4889442468              MOVQ AX, 0x68(SP)
  main.go:8             0x4cbcfb                48c744247001000000      MOVQ $0x1, 0x70(SP)
  main.go:8             0x4cbd04                48c744247801000000      MOVQ $0x1, 0x78(SP)
  main.go:8             0x4cbd0d                48890424                MOVQ AX, 0(SP)
  main.go:8             0x4cbd11                48c744240801000000      MOVQ $0x1, 0x8(SP)
  main.go:8             0x4cbd1a                48c744241001000000      MOVQ $0x1, 0x10(SP)
  main.go:8             0x4cbd23                e848fbffff              CALL log.Println(SB)
  main.go:9             0x4cbd28                c744241800000000        MOVL $0x0, 0x18(SP)
  main.go:9             0x4cbd30                488d0539550400          LEAQ go.func.*+154(SB), AX
  main.go:9             0x4cbd37                4889442430              MOVQ AX, 0x30(SP)
  main.go:9             0x4cbd3c                488d442418              LEAQ 0x18(SP), AX
  main.go:9             0x4cbd41                48890424                MOVQ AX, 0(SP)
  main.go:9             0x4cbd45                e8464cf6ff              CALL runtime.deferprocStack(SB)
  main.go:9             0x4cbd4a                85c0                    TESTL AX, AX
  main.go:9             0x4cbd4c                7518                    JNE 0x4cbd66
  main.go:9             0x4cbd4e                eb00                    JMP 0x4cbd50
  main.go:12            0x4cbd50                90                      NOPL
  main.go:12            0x4cbd51                e84a52f6ff              CALL runtime.deferreturn(SB)
  main.go:12            0x4cbd56                488bac2480000000        MOVQ 0x80(SP), BP
  main.go:12            0x4cbd5e                4881c488000000          ADDQ $0x88, SP
  main.go:12            0x4cbd65                c3                      RET
  main.go:9             0x4cbd66                90                      NOPL
  main.go:9             0x4cbd67                e83452f6ff              CALL runtime.deferreturn(SB)
  main.go:9             0x4cbd6c                488bac2480000000        MOVQ 0x80(SP), BP
  main.go:9             0x4cbd74                4881c488000000          ADDQ $0x88, SP
  main.go:9             0x4cbd7b                c3                      RET
  main.go:7             0x4cbd7c                e80fdef8ff              CALL runtime.morestack_noctxt(SB)
  main.go:7             0x4cbd81                e90affffff              JMP main.main.func1(SB)
  :-1                   0x4cbd86                cc                      INT $0x3
  :-1                   0x4cbd87                cc                      INT $0x3
  :-1                   0x4cbd88                cc                      INT $0x3
  :-1                   0x4cbd89                cc                      INT $0x3
  :-1                   0x4cbd8a                cc                      INT $0x3
  :-1                   0x4cbd8b                cc                      INT $0x3
  :-1                   0x4cbd8c                cc                      INT $0x3
  :-1                   0x4cbd8d                cc                      INT $0x3
  :-1                   0x4cbd8e                cc                      INT $0x3
  :-1                   0x4cbd8f                cc                      INT $0x3

TEXT main.main.func2(SB) .../main.go
  main.go:14            0x4cbd90                65488b0c2528000000      MOVQ GS:0x28, CX
  main.go:14            0x4cbd99                488b8900000000          MOVQ 0(CX), CX
  main.go:14            0x4cbda0                483b6110                CMPQ 0x10(CX), SP
  main.go:14            0x4cbda4                767a                    JBE 0x4cbe20
  main.go:14            0x4cbda6                4883ec50                SUBQ $0x50, SP
  main.go:14            0x4cbdaa                48896c2448              MOVQ BP, 0x48(SP)
  main.go:14            0x4cbdaf                488d6c2448              LEAQ 0x48(SP), BP
  main.go:15            0x4cbdb4                0f57c0                  XORPS X0, X0
  main.go:15            0x4cbdb7                0f11442420              MOVUPS X0, 0x20(SP)
  main.go:15            0x4cbdbc                488d442420              LEAQ 0x20(SP), AX
  main.go:15            0x4cbdc1                4889442418              MOVQ AX, 0x18(SP)
  main.go:15            0x4cbdc6                8400                    TESTB AL, 0(AX)
  main.go:15            0x4cbdc8                488d0d713b0100          LEAQ runtime.rodata+80192(SB), CX
  main.go:15            0x4cbdcf                48894c2420              MOVQ CX, 0x20(SP)
  main.go:15            0x4cbdd4                488d0d95d10400          LEAQ sync/atomic.CompareAndSwapUintptr.args_stackmap+400(SB), CX
  main.go:15            0x4cbddb                48894c2428              MOVQ CX, 0x28(SP)
  main.go:15            0x4cbde0                8400                    TESTB AL, 0(AX)
  main.go:15            0x4cbde2                eb00                    JMP 0x4cbde4
  main.go:15            0x4cbde4                4889442430              MOVQ AX, 0x30(SP)
  main.go:15            0x4cbde9                48c744243801000000      MOVQ $0x1, 0x38(SP)
  main.go:15            0x4cbdf2                48c744244001000000      MOVQ $0x1, 0x40(SP)
  main.go:15            0x4cbdfb                48890424                MOVQ AX, 0(SP)
  main.go:15            0x4cbdff                48c744240801000000      MOVQ $0x1, 0x8(SP)
  main.go:15            0x4cbe08                48c744241001000000      MOVQ $0x1, 0x10(SP)
  main.go:15            0x4cbe11                e85afaffff              CALL log.Println(SB)
  main.go:16            0x4cbe16                488b6c2448              MOVQ 0x48(SP), BP
  main.go:16            0x4cbe1b                4883c450                ADDQ $0x50, SP
  main.go:16            0x4cbe1f                c3                      RET
  main.go:14            0x4cbe20                e86bddf8ff              CALL runtime.morestack_noctxt(SB)
  main.go:14            0x4cbe25                e966ffffff              JMP main.main.func2(SB)

提取CALL

  main.go:6             0x4cba4b                e820feffff                      CALL log.Println(SB)
  main.go:7             0x4cba6d                e81e4ff6ff                      CALL runtime.deferprocStack(SB)
  main.go:13            0x4cbaf1                e87afdffff                      CALL log.Println(SB)
  main.go:14            0x4cbb13                e8784ef6ff                      CALL runtime.deferprocStack(SB)
  main.go:17            0x4cbb97                e8d4fcffff                      CALL log.Println(SB)
  main.go:18            0x4cbb9d                e8fe53f6ff                      CALL runtime.deferreturn(SB)
  main.go:14            0x4cbbb3                e8e853f6ff                      CALL runtime.deferreturn(SB)
  main.go:7             0x4cbbc9                e8d253f6ff                      CALL runtime.deferreturn(SB)
  main.go:5             0x4cbbde                e8addff8ff                      CALL runtime.morestack_noctxt(SB)
#################下面是 func1.1 的 CALL
  main.go:10            0x4cbc71                e8fafbffff              CALL log.Println(SB)
  main.go:9             0x4cbc80                e80bdff8ff              CALL runtime.morestack_noctxt(SB)
#################下面是 func1 的 CALL
  main.go:8             0x4cbd23                e848fbffff              CALL log.Println(SB)
  main.go:9             0x4cbd45                e8464cf6ff              CALL runtime.deferprocStack(SB)
  main.go:12            0x4cbd51                e84a52f6ff              CALL runtime.deferreturn(SB)
  main.go:9             0x4cbd67                e83452f6ff              CALL runtime.deferreturn(SB)
  main.go:7             0x4cbd7c                e80fdef8ff              CALL runtime.morestack_noctxt(SB)
#################下面是 func2 的 CALL
  main.go:15            0x4cbe11                e85afaffff              CALL log.Println(SB)
  main.go:14            0x4cbe20                e86bddf8ff              CALL runtime.morestack_noctxt(SB)

 

三、关键知识点汇总

1、defer 的实现一定是由编译器和运行时共同完成的

2、defer 关键字使用传值的方式传递参数时会进行预计算,导致不符合预期的结果

3、Go 语言中所有的函数调用都是传值的,虽然 defer 是关键字,但是也继承了这个特性

4、内存分配逃逸分析的场景需了解

5、对deferproc和deferreturn的机制做了解

6、return不是原子操作,执行过程是: 保存返回值(若有)-->执行defer(若有)-->执行ret跳转

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值