站长论坛 - 站长交流社区- SEO交流论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 93|回复: 1

[其他] 获得Go程序汇编代码的三个方法

[复制链接]
发表于 2019-4-16 18:18:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

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

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

once.go
1type Once struct {
2    m    sync.Mutex
3    done uint32
4}
5func (o *Once) Do(f func()) {
6    if atomic.LoadUint32(&o.done) == 1 {
7        return
8    }
9    o.m.Lock()
10    defer o.m.Unlock()
11    if o.done == 0 {
12        defer atomic.StoreUint32(&o.done, 1)
13        f()
14    }
15}
  
方法一: go tool compile
使用go tool compile -N -l -S once.go生成汇编代码:

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

方法二: go tool objdump
首先先编译程序: go tool compile -N -l once.go,

使用go tool objdump once.o反汇编出代码 (或者使用go tool objdump -s Do once.o反汇编特定的函数:):

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

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

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

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

回复

使用道具 举报

 楼主| 发表于 2019-6-15 19:30:48 | 显示全部楼层
。申请阿里云服务器等产品时,可以使用2000元阿里云代金券,阿里云官网领取网址: https://promotion.aliyun.com/ntm ... l?userCode=2a7uv47d
     特别提醒您:首次购买时先将所有要买的业务都加入到购物车,最后一起付款,这样才可享受优惠。如果一个一个买,那就只有首单才能享受优惠,从第2单开始就不能享受优惠了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|易采站长站 ( 蒙ICP备14002389-1号 ) |

GMT+8, 2019-8-26 18:13

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表