美文网首页
从原理上理解defer - golang

从原理上理解defer - golang

作者: frank3 | 来源:发表于2018-05-07 14:40 被阅读0次

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

    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,这个是如何处理的?

    得学习......

    相关文章

      网友评论

          本文标题:从原理上理解defer - golang

          本文链接:https://www.haomeiwen.com/subject/kdgmrftx.html