Go语言:import strings转化为汇编是什么样的?

Sat 10 October 2015 / In categories Programming Languages

Golang

回答题目中所提的这个问题,我们需要一点小小的背景知识。Go语言的汇编格式是从Plan9继承过来的,与我们常见的nasm和yasm都不相同。

先写一个简单的Go程序x.go

package foo

import (
        _ "strings"
)

上面的程序除了导入”strings”包以外什么都不干。

使用Go1.5的编译命令来输出反汇编: `回答题目中所提的这个问题,我们需要一点小小的背景知识。Go语言的汇编格式是从Plan9继承过来的,与我们常见的nasm和yasm都不相同。

先写一个简单的Go程序x.go

package foo

import (
        _ "strings"
)

上面的程序除了导入”strings”包以外什么都不干。

使用Go1.5的编译命令来输出反汇编:`

注意我的编译环境是windows_amd64.

几个选项的含义如下:

  • -S 反汇编
  • -v 输出更多内容
  • -N 禁止优化
  • -l 禁止内联

删掉输出内容不相关的部分,并适当调整了顺序,可以得到:

obj: 00000 (x.go:6)     TEXT    "".init(SB), $0-0
obj: 00019 (x.go:6)     CALL    strings.init(SB)
obj: 00021 (x.go:6)     RET

obj: 00000 (x.go:6)     DATA    go.string."strings"(SB), 7, $"strings"
obj: 00000 (x.go:6)     GLOBL   go.string."strings"(SB), $8

obj: 00000 (x.go:6)     DATA    go.string.hdr."strings"(SB), 8, $go.string."strings"(SB)
obj: 00000 (x.go:6)     GLOBL   go.string.hdr."strings"(SB), $16

obj: 00000 (x.go:6)     DATA    go.importpath.strings.(SB), 8, $go.string."strings"(SB)
obj: 00000 (x.go:6)     DATA    go.importpath.strings.+8(SB), 8, $7
obj: 00000 (x.go:6)     GLOBL   go.importpath.strings.(SB), $16

编译每个.go文件会生成相应的.o文件(object文件),每个object文件都有一个初始化函数init,因为strings包被import了,所以x.go的init函数中调用了strings.init:

obj: 00019 (x.go:6)     CALL    strings.init(SB)

import "strings"这条语句中,"strings"是作为一个字符串,所以它必须在全局数据段定义:

DATA    go.string."strings"(SB), 7, $"strings"

在SB,即Static Base定义了一个7字节的字符串$"string",并给这个字符串取名go.string."strings"。接下来的

GLOBL   go.string."strings"(SB), $8

帮助申明这个数据是全局的,大小被调整为8个字节,因为要与am64的8字节字长对齐。

接下来又定义了go.string.hdr."strings"(SB),共16个字节,前面8个字节用来保存$go.string."strings"(SB),也就是"string"地址;后面8个字节空着不用,很可能是链接的时候重定向用的。

最后定义了go.importpath.strings.(SB),也是16个字节,前面8个字节同样用来保存"string"地址,后面8个字节保存了"string"的长度。 估计这条数据告诉链接器要导入哪个包。

(完)

Load Disqus Comments