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

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

内容简介:有多种方式可以获得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

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

查看所有标签

猜你喜欢:

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

Windows API编程范例入门与提高

Windows API编程范例入门与提高

东方人华 / 清华大学出版社 / 2004-1-1 / 38.00

本书通过大量实用、经典的范例,以Visual Basic为开发平台由浅入深地介绍了Windows API编程的基本方法和大量的实用技巧。本书采用实例带动知识点的形式,使读者快速入门并逐步得到提高。本书每节即是一个实例,操作步骤详尽,所用到的源文件均可在网站下载。读者可以按照操作步骤完成每个实例的制作,并根据自己的喜好进行修改、举一反三。 本书内容翔实,凝结了作者多年的编程经验,既适合......一起来看看 《Windows API编程范例入门与提高》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具