从原理上理解defer - golang

2018-05-07  本文已影响0人  frank3

首先可以参考这位大神的文章, 以下内容是在大神文章的指导下,做的实践。

package main

import "fmt"

func main() {
    test()
}

func test() int {
    defer dfun()
    defer dfun2()
    return 1
}

func dfun()  {
    fmt.Printf("i am defer")
}

func dfun2() (string, map[int]int){
    fmt.Printf("i am defer")

    return "", nil
}

test汇编代码:

0000000001095120         mov        rcx, qword [gs:0x8a0]                       ; CODE XREF=main.main+29, main.test+160
0000000001095129         cmp        rsp, qword [rcx+0x10]
000000000109512d         jbe        loc_10951bb

0000000001095133         sub        rsp, 0x30
0000000001095137         mov        qword [rsp+0x30+var_8], rbp
000000000109513c         lea        rbp, qword [rsp+0x30+var_8]
0000000001095141         mov        qword [rsp+0x30+arg_0], 0x0
000000000109514a         mov        dword [rsp+0x30+var_30], 0x0
0000000001095151         lea        rax, qword [go.func.*+126]
0000000001095158         mov        qword [rsp+0x30+var_28], rax
000000000109515d         call       runtime.deferproc
0000000001095162         test       eax, eax
0000000001095164         jne        loc_10951ab

0000000001095166         mov        dword [rsp+0x30+var_30], 0x18
000000000109516d         lea        rax, qword [go.func.*+118]
0000000001095174         mov        qword [rsp+0x30+var_28], rax
0000000001095179         call       runtime.deferproc
000000000109517e         test       eax, eax
0000000001095180         jne        loc_109519b

0000000001095182         mov        qword [rsp+0x30+arg_0], 0x1
000000000109518b         nop
000000000109518c         call       runtime.deferreturn
0000000001095191         mov        rbp, qword [rsp+0x30+var_8]
0000000001095196         add        rsp, 0x30
000000000109519a         ret
                        ; endp

可以看到:确实return 1 被分解了, 先对返回值进行赋值mov qword [rsp+0x30+arg_0] 然后调用了defer函数,最后进行空ret

我们又产生了,新的问题:
1、golang对返回值是如何规定的?

  1. 多个runtime.deferproc,但是只有一个runtime.deferreturn,这个是如何处理的?

得学习......

上一篇 下一篇

猜你喜欢

热点阅读