得到Go程序的汇编代码的方法

栏目: 编程语言 · 发布时间: 7年前

内容简介:有多种方式可以获得Go程序的汇编代码, 尽管输出的格式有些不同,但是都是方便阅读的汇编代码,可以帮助我们更好的了解程序的底层运行方式。我们看下面一段代码, 它是使用

有多种方式可以获得 Go 程序的汇编代码, 尽管输出的格式有些不同,但是都是方便阅读的汇编代码,可以帮助我们更好的了解程序的底层运行方式。

我们看下面一段代码, 它是 sync.Once 的实现,去掉了不必要的注释,复制出来用来研究的一段小代码。

once.go
type Once struct {
 m sync.Mutex
 done uint32
}

func (o *Once) Do(f func()) {
 if atomic.LoadUint32(&o.done) ==1 {
 return
 }

 o.m.Lock()
 defer o.m.Unlock()
 if o.done ==0 {
 defer atomic.StoreUint32(&o.done,1)
 f()
 }
}

方法一: go tool compile

使用 go tool compile -S once.go 生成汇编代码:

"".(*Once).Do STEXT size=239 args=0x10 locals=0x28
	0x0000 00000 (once.go:13)	TEXT	"".(*Once).Do(SB), $40-16
	0x0000 00000 (once.go:13)	MOVQ	(TLS), CX
	0x0009 00009 (once.go:13)	CMPQ	SP, 16(CX)
	0x000d 00013 (once.go:13)	JLS	229
	0x0013 00019 (once.go:13)	SUBQ	$40, SP
	0x0017 00023 (once.go:13)	MOVQ	BP, 32(SP)
	0x001c 00028 (once.go:13)	LEAQ	32(SP), BP
	0x0021 00033 (once.go:13)	FUNCDATA	$0, gclocals·fdbf1f5761f6d17e8ae3f0aaecb6a3c5(SB)
	0x0021 00033 (once.go:13)	FUNCDATA	$1, gclocals·7d2d5fca80364273fb07d5820a76fef4(SB)
	0x0021 00033 (once.go:13)	FUNCDATA	$3, gclocals·96839595c383af6ae8227769d90a999e(SB)
	0x0021 00033 (once.go:14)	PCDATA	$2, $1
	0x0021 00033 (once.go:14)	PCDATA	$0, $0
	0x0021 00033 (once.go:14)	MOVQ	"".o+48(SP), AX
	0x0026 00038 (once.go:14)	MOVL	8(AX), CX
	0x0029 00041 (once.go:14)	CMPL	CX, $1
	0x002c 00044 (once.go:14)	JEQ	213
	0x0032 00050 (once.go:18)	PCDATA	$2, $0
	0x0032 00050 (once.go:18)	MOVQ	AX, (SP)
	0x0036 00054 (once.go:18)	CALL	sync.(*Mutex).Lock(SB)
	0x003b 00059 (once.go:19)	PCDATA	$2, $1
	0x003b 00059 (once.go:19)	MOVQ	"".o+48(SP), AX

    ……

方法二: go tool compile

首先先编译程序: go tool compile once.go ,

使用 go tool objdump once.o 反汇编出代码:

TEXT %22%22.(*Once).Do(SB) gofile../Users/……/once.go
once.go:13		0x7cd			65488b0c2500000000	MOVQ GS:0, CX			[5:9]R_TLS_LE
once.go:13		0x7d6			483b6110		CMPQ 0x10(CX), SP
once.go:13		0x7da			0f86d2000000		JBE 0x8b2
once.go:13		0x7e0			4883ec28		SUBQ $0x28, SP
once.go:13		0x7e4			48896c2420		MOVQ BP, 0x20(SP)
once.go:13		0x7e9			488d6c2420		LEAQ 0x20(SP), BP
once.go:14		0x7ee			488b442430		MOVQ 0x30(SP), AX
once.go:14		0x7f3			8b4808			MOVL 0x8(AX), CX
once.go:14		0x7f6			83f901			CMPL $0x1, CX
once.go:14		0x7f9			0f84a3000000		JE 0x8a2
once.go:18		0x7ff			48890424		MOVQ AX, 0(SP)
once.go:18		0x803			e800000000		CALL 0x808			[1:5]R_CALL:sync.(*Mutex).Lock
once.go:19		0x808			488b442430		MOVQ 0x30(SP), AX
once.go:19		0x80d			4889442410		MOVQ AX, 0x10(SP)
once.go:19		0x812			c7042408000000		MOVL $0x8, 0(SP)

  ……

方法三: go build -gcflags -S

使用 go build -gcflags -S once.go 也可以得到汇编代码:

"".(*Once).Do STEXT size=239 args=0x10 locals=0x28
	0x0000 00000 (/Users/……/once.go:13)	TEXT	"".(*Once).Do(SB), $40-16
	0x0000 00000 (/Users/……/once.go:13)	MOVQ	(TLS), CX
	0x0009 00009 (/Users/……/once.go:13)	CMPQ	SP, 16(CX)
	0x000d 00013 (/Users/……/once.go:13)	JLS	229
	0x0013 00019 (/Users/……/once.go:13)	SUBQ	$40, SP
	0x0017 00023 (/Users/……/once.go:13)	MOVQ	BP, 32(SP)
	0x001c 00028 (/Users/……/once.go:13)	LEAQ	32(SP), BP
	0x0021 00033 (/Users/……/once.go:13)	FUNCDATA	$0, gclocals·fdbf1f5761f6d17e8ae3f0aaecb6a3c5(SB)
	0x0021 00033 (/Users/……/once.go:13)	FUNCDATA	$1, gclocals·7d2d5fca80364273fb07d5820a76fef4(SB)
	0x0021 00033 (/Users/……/once.go:13)	FUNCDATA	$3, gclocals·96839595c383af6ae8227769d90a999e(SB)
	0x0021 00033 (/Users/……/once.go:14)	PCDATA	$2, $1
	0x0021 00033 (/Users/……/once.go:14)	PCDATA	$0, $0
	0x0021 00033 (/Users/……/once.go:14)	MOVQ	"".o+48(SP), AX
	0x0026 00038 (/Users/……/once.go:14)	MOVL	8(AX), CX
	0x0029 00041 (/Users/……/once.go:14)	CMPL	CX, $1
	0x002c 00044 (/Users/……/once.go:14)	JEQ	213

go tool compilego build -gcflags -S 生成的是过程中的汇编,和最终的机器码的汇编可以通过 go tool objdump 生成。

参考文档

  1. https://www.reddit.com/r/golang/comments/6a5557/how_to_get_assembly_output_from_a_small_go_program/
  2. https://stackoverflow.com/questions/43858356/how-to-get-assembly-output-for-a-short-go-program
  3. https://rakyll.org/codegen/
  4. https://stackoverflow.com/questions/22769246/how-to-disassemble-one-single-function-using-objdump

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Algorithm Design Manual

The Algorithm Design Manual

Steve S. Skiena / Springer / 1998-8-1 / GBP 53.91

Contents u Techniques u Introduction to Algorithms u Correctness and Efficiency u Correctness u Efficiency u Expressing Algorithms u Keeping Score u The RAM Model of Computatio......一起来看看 《The Algorithm Design Manual》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具