golang 反汇编代码阅读-- defer

先看源码

package main



//!+f
func main() {
	f1()
	f2()
	f3()

}

func f1() (result int) {
	defer func() {
		result++
	}()
	return 0
}

func f2() (r int) {
	t := 5
	defer func() {
		t = t + 5
	}()
	return t
}

func f3() (r int) {
	defer func(r int) {
		r = r + 5
	}(r)
	return 1
}

 再看反汇编代码

000000000044c320 <main.f1.func1>:
  44c320:	48 8b 44 24 08       	mov    0x8(%rsp),%rax
  44c325:	48 ff 00             	incq   (%rax)
  44c328:	c3                   	retq   
  44c329:	cc                   	int3   
  44c32a:	cc                   	int3   
  44c32b:	cc                   	int3   
  44c32c:	cc                   	int3   
  44c32d:	cc                   	int3   
  44c32e:	cc                   	int3   
  44c32f:	cc                   	int3   

000000000044c330 <main.f2.func1>:
  44c330:	48 8b 44 24 08       	mov    0x8(%rsp),%rax
  44c335:	48 83 00 05          	addq   $0x5,(%rax)
  44c339:	c3                   	retq   
  44c33a:	cc                   	int3   
  44c33b:	cc                   	int3   
  44c33c:	cc                   	int3   
  44c33d:	cc                   	int3   
  44c33e:	cc                   	int3   
  44c33f:	cc                   	int3   

000000000044c340 <main.f3.func1>:
  44c340:	c3                   	retq   
  44c341:	cc                   	int3   
  44c342:	cc                   	int3   
  44c343:	cc                   	int3   
  44c344:	cc                   	int3   
  44c345:	cc                   	int3   
  44c346:	cc                   	int3   
  44c347:	cc                   	int3   
  44c348:	cc                   	int3   
  44c349:	cc                   	int3   
  44c34a:	cc                   	int3   
  44c34b:	cc                   	int3   
  44c34c:	cc                   	int3   
  44c34d:	cc                   	int3   
  44c34e:	cc                   	int3   
  44c34f:	cc                   	int3   

 那么多的 int3 是为了保证函数栈是对齐的? yes it is ! some compiler use nop, others use int3 !

000000000044c150 <main.main>:
  44c150:	64 48 8b 0c 25 f8 ff 	mov    %fs:0xfffffffffffffff8,%rcx
  44c157:	ff ff 
  44c159:	48 3b 61 10          	cmp    0x10(%rcx),%rsp
  44c15d:	76 27                	jbe    44c186 <main.main+0x36>
  44c15f:	48 83 ec 10          	sub    $0x10,%rsp
  44c163:	48 89 6c 24 08       	mov    %rbp,0x8(%rsp)
  44c168:	48 8d 6c 24 08       	lea    0x8(%rsp),%rbp
  44c16d:	e8 1e 00 00 00       	callq  44c190 <main.f1>
  44c172:	e8 99 00 00 00       	callq  44c210 <main.f2>
  44c177:	e8 24 01 00 00       	callq  44c2a0 <main.f3>
  44c17c:	48 8b 6c 24 08       	mov    0x8(%rsp),%rbp
  44c181:	48 83 c4 10          	add    $0x10,%rsp
  44c185:	c3                   	retq   
  44c186:	e8 e5 83 ff ff       	callq  444570 <runtime.morestack_noctxt>
  44c18b:	eb c3                	jmp    44c150 <main.main>
  44c18d:	cc                   	int3   
  44c18e:	cc                   	int3   
  44c18f:	cc                   	int3   

 为什么大部分的函数都是先 mov,cmp, jbe 到 runtime.morestack_noctxt 那里? 据说和连续栈有关,而且还涉及到黑科技!留给以后研究

原文地址:https://www.cnblogs.com/tmortred/p/9911998.html