首先可以参考这位大神的文章, 以下内容是在大神文章的指导下,做的实践。
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对返回值是如何规定的?
- 多个runtime.deferproc,但是只有一个runtime.deferreturn,这个是如何处理的?
得学习......