Chapter 1 addon: A Complete View of Golang Hello World

Go004 a Complete View of Golang Hello World

Chapter 1 addon: A Complete View of Golang Hello World
Page content

Hello World

运行 Hello World

“Hello World” 是学习一门新的编程语言的约定俗成的开始,这篇文章分析一下 分析Golang语言的"Hello World"是如何工作的,包括一些编译原理的知识和go相关
cli工具命令的基本使用

“Hello World"从源文件到用户看到"Hello World"的大致过程:

hello_world.go源码 --> go build hello_world.go --> 词法分析(scanner or lexer)) -------

                           hello_world.go AST
-----> 语法分析(parser) ----------------------> 类型检查 --> 中间代码生成 --> 代码优化(SSA) --> 机器码生成 --> 运行

下面是手动编译main包,并运行的过程

...
root@[18:30:17]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]
# ls -1
go.mod
hello_world.go # hello world 源码

root@[18:30:20]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]
# cat hello_world.go
package main

import (
        "fmt"
)

func main() {
        fmt.Println("Hello World!")
}

root@[18:30:21]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]
# go build hello_world.go # 编译和链接

root@[18:30:27]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]
# ls -1
go.mod
hello_world    # 生成的可执行二进制机器文件
hello_world.go

root@[18:30:37]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]
# file -i hello_world
hello_world: application/x-executable; charset=binary  # mime 格式为可执行文件类型

root@[18:30:42]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]
# file hello_world
hello_world: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=Z5tT9XDXjWPVZk9ptG4y/RyMMuw-KGted2bhuJAWr/-pVyHxEx6QwId4IaOfIS/XGy4YinIHBCvJFzpOgjl, not stripped

root@[18:31:12]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]
# readelf -h hello_world  # ELF 头信息
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x4647e0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          456 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         7
  Size of section headers:           64 (bytes)
  Number of section headers:         25
  Section header string table index: 3

root@[18:31:48]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]
# ./hello_world # run executable machine code
Hello World! 
...

在使用命令go build构建时我指定了hello_world.go,此时go build会编译hello_world.go所属的包(main包)
如果还有其它文件属于main包,那此次编译将不成功,因为go build是以包为编译单元的,如果有多个文件属于
同一个包,则需要指定该包下所有的.go文件。此处我只有一个.go文件,并且只有一个main包,所以只指定
hello_world.go即可,也可以在当前文件夹直接使用go build或者go build ./

go build执行时大致经过了6个步骤:

  1. hello_world.go 的词法分析

  2. hello_world.go 的语法分析

  3. hello_world.go 的类型检查

  4. hello_world.go 的中间代码生成

  5. hello_world.go 代码优化

  6. hello_world.go 的机器码生成(生成二进制可执行文件)

在第2步的语法分析过程中会生成hello_world.go的AST:Abstract Syntax Tree(抽象语法树), 在wiki上 对AST的解释是: AST是对某门编程语言所编写的源代码的语法结构树形表示1

hello_world.go 的语法树

Dump
     0  *ast.File {
     1  .  Package: 1:1
     2  .  Name: *ast.Ident {
     3  .  .  NamePos: 1:9
     4  .  .  Name: "main"
     5  .  }
     6  .  Decls: []ast.Decl (len = 2) {
     7  .  .  0: *ast.GenDecl {
     8  .  .  .  TokPos: 3:1
     9  .  .  .  Tok: import
    10  .  .  .  Lparen: 3:8
    11  .  .  .  Specs: []ast.Spec (len = 1) {
    12  .  .  .  .  0: *ast.ImportSpec {
    13  .  .  .  .  .  Path: *ast.BasicLit {
    14  .  .  .  .  .  .  ValuePos: 4:2
    15  .  .  .  .  .  .  Kind: STRING
    16  .  .  .  .  .  .  Value: "\"fmt\""
    17  .  .  .  .  .  }
    18  .  .  .  .  .  EndPos: -
    19  .  .  .  .  }
    20  .  .  .  }
    21  .  .  .  Rparen: 5:1
    22  .  .  }
    23  .  .  1: *ast.FuncDecl {
    24  .  .  .  Name: *ast.Ident {
    25  .  .  .  .  NamePos: 7:6
    26  .  .  .  .  Name: "main"
    27  .  .  .  .  Obj: *ast.Object {
    28  .  .  .  .  .  Kind: func
    29  .  .  .  .  .  Name: "main"
    30  .  .  .  .  .  Decl: *(obj @ 23)
    31  .  .  .  .  }
    32  .  .  .  }
    33  .  .  .  Type: *ast.FuncType {
    34  .  .  .  .  Func: 7:1
    35  .  .  .  .  Params: *ast.FieldList {
    36  .  .  .  .  .  Opening: 7:10
    37  .  .  .  .  .  Closing: 7:11
    38  .  .  .  .  }
    39  .  .  .  }
    40  .  .  .  Body: *ast.BlockStmt {
    41  .  .  .  .  Lbrace: 7:13
    42  .  .  .  .  List: []ast.Stmt (len = 1) {
    43  .  .  .  .  .  0: *ast.ExprStmt {
    44  .  .  .  .  .  .  X: *ast.CallExpr {
    45  .  .  .  .  .  .  .  Fun: *ast.SelectorExpr {
    46  .  .  .  .  .  .  .  .  X: *ast.Ident {
    47  .  .  .  .  .  .  .  .  .  NamePos: 8:2
    48  .  .  .  .  .  .  .  .  .  Name: "fmt"
    49  .  .  .  .  .  .  .  .  }
    50  .  .  .  .  .  .  .  .  Sel: *ast.Ident {
    51  .  .  .  .  .  .  .  .  .  NamePos: 8:6
    52  .  .  .  .  .  .  .  .  .  Name: "Println"
    53  .  .  .  .  .  .  .  .  }
    54  .  .  .  .  .  .  .  }
    55  .  .  .  .  .  .  .  Lparen: 8:13
    56  .  .  .  .  .  .  .  Args: []ast.Expr (len = 1) {
    57  .  .  .  .  .  .  .  .  0: *ast.BasicLit {
    58  .  .  .  .  .  .  .  .  .  ValuePos: 8:14
    59  .  .  .  .  .  .  .  .  .  Kind: STRING
    60  .  .  .  .  .  .  .  .  .  Value: "\"Hello, world!\""
    61  .  .  .  .  .  .  .  .  }
    62  .  .  .  .  .  .  .  }
    63  .  .  .  .  .  .  .  Ellipsis: -
    64  .  .  .  .  .  .  .  Rparen: 8:29
    65  .  .  .  .  .  .  }
    66  .  .  .  .  .  }
    67  .  .  .  .  }
    68  .  .  .  .  Rbrace: 9:1
    69  .  .  .  }
    70  .  .  }
    71  .  }
    72  .  Scope: *ast.Scope {
    73  .  .  Objects: map[string]*ast.Object (len = 1) {
    74  .  .  .  "main": *(obj @ 27)
    75  .  .  }
    76  .  }
    77  .  Imports: []*ast.ImportSpec (len = 1) {
    78  .  .  0: *(obj @ 12)
    79  .  }
    80  .  Unresolved: []*ast.Ident (len = 1) {
    81  .  .  0: *(obj @ 46)
    82  .  }
    83  }

可以看到File.Decls[1].Body.List[0]清楚的描述了fmt包的Println函数和接收的参数"Hello, world!”
另外,比如Decls域中,包含了hello_world.go中所有的声明,如: 导入import,常量声明const,变量var和函数func。
而本例中,声明只有import和func,分别是导入fmt包和main函数的声明。

SSA

[11:02:57]suosuoli:[/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test]                                                                                     ## GOSSAFUNC=main GOOS=linux GOARCH=amd64 go build -gcflags "-S" hello_world.go                                                                                             # runtime
dumped SSA to /usr/local/go/src/runtime/ssa.html  # SSA 写入的位置
# command-line-arguments                                                                                                                                                   umped SSA to ./ssa.html                                                                                                                                                    os.(*File).close STEXT dupok nosplit size=26 args=0x18 locals=0x0                                                                                                                  0x0000 00000 (<autogenerated>:1) TEXT   os.(*File).close(SB), DUPOK|NOSPLIT|ABIInternal, $0-24
        0x0000 00000 (<autogenerated>:1) FUNCDATA      $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
        0x0000 00000 (<autogenerated>:1) FUNCDATA      $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
        0x0000 00000 (<autogenerated>:1) MOVQ   ""..this+8(SP), AX                                                                                                                 0x0005 00005 (<autogenerated>:1) MOVQ   (AX), AX                                                                                                                           0x0008 00008 (<autogenerated>:1) MOVQ   AX, ""..this+8(SP)                                                                                                                 0x000d 00013 (<autogenerated>:1) XORPS  X0, X0                                                                                                                             0x0010 00016 (<autogenerated>:1) MOVUPS X0, "".~r0+16(SP)
        0x0015 00021 (<autogenerated>:1) JMP    os.(*file).close(SB)
        0x0000 48 8b 44 24 08 48 8b 00 48 89 44 24 08 0f 57 c0  H.D$.H..H.D$..W.
        0x0010 0f 11 44 24 10 e9 00 00 00 00                    ..D$......
        rel 22+4 t=8 os.(*file).close+0
"".main STEXT size=138 args=0x0 locals=0x58
        0x0000 00000 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        TEXT    "".main(SB), ABIInternal, $88-0                            0x0000 00000 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        MOVQ    (TLS), CX                                                  0x0009 00009 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        CMPQ    SP, 16(CX)
        0x000d 00013 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        PCDATA  $0, $-2                                                    0x000d 00013 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        JLS     128                                                        0x000f 00015 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        PCDATA  $0, $-1
        0x000f 00015 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        SUBQ    $88, SP                                                    0x0013 00019 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        MOVQ    BP, 80(SP)                                                 0x0018 00024 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        LEAQ    80(SP), BP                                                 0x001d 00029 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        FUNCDATA        $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
        0x001d 00029 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        FUNCDATA        $1, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
        0x001d 00029 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        FUNCDATA        $3, "".main.stkobj(SB)
        0x001d 00029 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        XORPS   X0, X0                                                     0x0020 00032 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        MOVUPS  X0, ""..autotmp_11+64(SP)                                  0x0025 00037 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        LEAQ    type.string(SB), AX                                        0x002c 00044 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        MOVQ    AX, ""..autotmp_11+64(SP)                                  0x0031 00049 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        LEAQ    ""..stmp_0(SB), AX                                         0x0038 00056 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        MOVQ    AX, ""..autotmp_11+72(SP)                                  0x003d 00061 (<unknown line number>)    NOP
        0x003d 00061 ($GOROOT/src/fmt/print.go:274)    MOVQ     os.Stdout(SB), AX
        0x0044 00068 ($GOROOT/src/fmt/print.go:274)    LEAQ     go.itab.*os.File,io.Writer(SB), CX                                                                                 0x004b 00075 ($GOROOT/src/fmt/print.go:274)    MOVQ     CX, (SP)
        0x004f 00079 ($GOROOT/src/fmt/print.go:274)    MOVQ     AX, 8(SP)                                                                                                          0x0054 00084 ($GOROOT/src/fmt/print.go:274)    LEAQ     ""..autotmp_11+64(SP), AX
        0x0059 00089 ($GOROOT/src/fmt/print.go:274)    MOVQ     AX, 16(SP)
        0x005e 00094 ($GOROOT/src/fmt/print.go:274)    MOVQ     $1, 24(SP)                                                                                                         0x0067 00103 ($GOROOT/src/fmt/print.go:274)    MOVQ     $1, 32(SP)                                                                                                         0x0070 00112 ($GOROOT/src/fmt/print.go:274)    PCDATA   $1, $0
        0x0070 00112 ($GOROOT/src/fmt/print.go:274)    CALL     fmt.Fprintln(SB)
        0x0075 00117 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        MOVQ    80(SP), BP                                                 0x007a 00122 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        ADDQ    $88, SP                                                    0x007e 00126 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        RET                                                                0x007f 00127 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:8)        NOP
        0x007f 00127 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        PCDATA  $1, $-1
        0x007f 00127 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        PCDATA  $0, $-2
        0x007f 00127 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        NOP                                                                0x0080 00128 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        CALL    runtime.morestack_noctxt(SB)                               0x0085 00133 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        PCDATA  $0, $-1                                                    0x0085 00133 (/usr/local/openresty/nginx/html/go_draft_codes/golang/codes/test/hello_world.go:7)        JMP     0                                                          0x0000 64 48 8b 0c 25 00 00 00 00 48 3b 61 10 76 71 48  dH..%....H;a.vqH
        0x0010 83 ec 58 48 89 6c 24 50 48 8d 6c 24 50 0f 57 c0  ..XH.l$PH.l$P.W.
        0x0020 0f 11 44 24 40 48 8d 05 00 00 00 00 48 89 44 24  ..D$@H......H.D$
        0x0030 40 48 8d 05 00 00 00 00 48 89 44 24 48 48 8b 05  @H......H.D$HH..
        0x0040 00 00 00 00 48 8d 0d 00 00 00 00 48 89 0c 24 48  ....H......H..$H
        0x0050 89 44 24 08 48 8d 44 24 40 48 89 44 24 10 48 c7  .D$.H.D$@H.D$.H.
        0x0060 44 24 18 01 00 00 00 48 c7 44 24 20 01 00 00 00  D$.....H.D$ ....                                                                                                   0x0070 e8 00 00 00 00 48 8b 6c 24 50 48 83 c4 58 c3 90  .....H.l$PH..X..                                                                                                   0x0080 e8 00 00 00 00 e9 76 ff ff ff                    ......v...
        rel 5+4 t=17 TLS+0                                                                                                                                                         rel 40+4 t=16 type.string+0                                                                                                                                                rel 52+4 t=16 ""..stmp_0+0                                                                                                                                                 rel 64+4 t=16 os.Stdout+0                                                                                                                                                  rel 71+4 t=16 go.itab.*os.File,io.Writer+0                                                                                                                                 rel 113+4 t=8 fmt.Fprintln+0                                                                                                                                               rel 129+4 t=8 runtime.morestack_noctxt+0                                                                                                                               go.cuinfo.packagename.main SDWARFINFO dupok size=0
        0x0000 6d 61 69 6e                                      main                                                                                                           go.info.fmt.Println$abstract SDWARFINFO dupok size=42
        0x0000 04 66 6d 74 2e 50 72 69 6e 74 6c 6e 00 01 01 11  .fmt.Println....                                                                                                   0x0010 61 00 00 00 00 00 00 11 6e 00 01 00 00 00 00 11  a.......n.......                                                                                                   0x0020 65 72 72 00 01 00 00 00 00 00                    err.......                                                                                                         rel 0+0 t=24 type.[]interface {}+0                                                                                                                                         rel 0+0 t=24 type.error+0                                                                                                                                                  rel 0+0 t=24 type.int+0                                                                                                                                                    rel 19+4 t=29 go.info.[]interface {}+0                                                                                                                                     rel 27+4 t=29 go.info.int+0
        rel 37+4 t=29 go.info.error+0
go.string."Hello World!" SRODATA dupok size=12                                                                                                                                     0x0000 48 65 6c 6c 6f 20 57 6f 72 6c 64 21              Hello World!
runtime.nilinterequal·f SRODATA dupok size=8                                                                                                                                       0x0000 00 00 00 00 00 00 00 00                          ........                                                                                                           rel 0+8 t=1 runtime.nilinterequal+0
runtime.memequal64·f SRODATA dupok size=8                                                                                                                                          0x0000 00 00 00 00 00 00 00 00                          ........                                                                                                           rel 0+8 t=1 runtime.memequal64+0
runtime.gcbits.01 SRODATA dupok size=1
        0x0000 01                                               .                                                                                                              type..namedata.*interface {}- SRODATA dupok size=16                                                                                                                            0x0000 00 00 0d 2a 69 6e 74 65 72 66 61 63 65 20 7b 7d  ...*interface {}                                                                                               type.*interface {} SRODATA dupok size=56                                                                                                                                       0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................                                                                                                   0x0010 4f 0f 96 9d 08 08 08 36 00 00 00 00 00 00 00 00  O......6........                                                                                                   0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................                                                                                                   0x0030 00 00 00 00 00 00 00 00                          ........                                                                                                           rel 24+8 t=1 runtime.memequal64·f+0                                                                                                                                        rel 32+8 t=1 runtime.gcbits.01+0                                                                                                                                           rel 40+4 t=5 type..namedata.*interface {}-+0
        rel 48+8 t=1 type.interface {}+0
runtime.gcbits.02 SRODATA dupok size=1
        0x0000 02                                               .
type.interface {} SRODATA dupok size=80
        0x0000 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00  ................
        0x0010 e7 57 a0 18 02 08 08 14 00 00 00 00 00 00 00 00  .W..............                                                                                                   0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................                                                                                                   0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
		0x0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................                                                                                                   rel 24+8 t=1 runtime.nilinterequal·f+0                                                                                                                                     rel 32+8 t=1 runtime.gcbits.02+0                                                                                                                                           rel 40+4 t=5 type..namedata.*interface {}-+0                                                                                                                               rel 44+4 t=6 type.*interface {}+0                                                                                                                                          rel 56+8 t=1 type.interface {}+80                                                                                                                                      type..namedata.*[]interface {}- SRODATA dupok size=18                                                                                                                          0x0000 00 00 0f 2a 5b 5d 69 6e 74 65 72 66 61 63 65 20  ...*[]interface
        0x0010 7b 7d                                            {}                                                                                                             type.*[]interface {} SRODATA dupok size=56
        0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................                                                                                                   0x0010 f3 04 9a e7 08 08 08 36 00 00 00 00 00 00 00 00  .......6........                                                                                                   0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................                                                                                                   0x0030 00 00 00 00 00 00 00 00                          ........                                                                                                           rel 24+8 t=1 runtime.memequal64·f+0                                                                                                                                        rel 32+8 t=1 runtime.gcbits.01+0                                                                                                                                           rel 40+4 t=5 type..namedata.*[]interface {}-+0                                                                                                                             rel 48+8 t=1 type.[]interface {}+0
type.[]interface {} SRODATA dupok size=56
        0x0000 18 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................                                                                                                   0x0010 70 93 ea 2f 02 08 08 17 00 00 00 00 00 00 00 00  p../............
        0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................                                                                                                   0x0030 00 00 00 00 00 00 00 00                          ........                                                                                                           rel 32+8 t=1 runtime.gcbits.01+0
        rel 40+4 t=5 type..namedata.*[]interface {}-+0                                                                                                                             rel 44+4 t=6 type.*[]interface {}+0                                                                                                                                        rel 48+8 t=1 type.interface {}+0
type..namedata.*[1]interface {}- SRODATA dupok size=19
        0x0000 00 00 10 2a 5b 31 5d 69 6e 74 65 72 66 61 63 65  ...*[1]interface                                                                                                   0x0010 20 7b 7d                                          {}                                                                                                        type.*[1]interface {} SRODATA dupok size=56                                                                                                                                        0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................                                                                                                   0x0010 bf 03 a8 35 08 08 08 36 00 00 00 00 00 00 00 00  ...5...6........                                                                                                   0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................                                                                                                   0x0030 00 00 00 00 00 00 00 00                          ........                                                                                                           rel 24+8 t=1 runtime.memequal64·f+0                                                                                                                                        rel 32+8 t=1 runtime.gcbits.01+0                                                                                                                                           rel 40+4 t=5 type..namedata.*[1]interface {}-+0                                                                                                                            rel 48+8 t=1 type.[1]interface {}+0
type.[1]interface {} SRODATA dupok size=72
        0x0000 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00  ................
        0x0010 50 91 5b fa 02 08 08 11 00 00 00 00 00 00 00 00  P.[.............
        0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        0x0040 01 00 00 00 00 00 00 00                          ........                                                                                                           rel 24+8 t=1 runtime.nilinterequal·f+0                                                                                                                                     rel 32+8 t=1 runtime.gcbits.02+0
        rel 40+4 t=5 type..namedata.*[1]interface {}-+0                                                                                                                            rel 44+4 t=6 type.*[1]interface {}+0                                                                                                                                       rel 48+8 t=1 type.interface {}+0                                                                                                                                           rel 56+8 t=1 type.[]interface {}+0                                                                                                                                 go.string."0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\tcommand-line-arguments\nmod\ttest\t(devel)\t\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2" SRODATA dupok size=78    0x0000 30 77 af 0c 92 74 08 02 41 e1 c1 07 e6 d6 18 e6  0w...t..A.......                                                                                                   0x0010 70 61 74 68 09 63 6f 6d 6d 61 6e 64 2d 6c 69 6e  path.command-lin                                                                                                   0x0020 65 2d 61 72 67 75 6d 65 6e 74 73 0a 6d 6f 64 09  e-arguments.mod.
        0x0030 74 65 73 74 09 28 64 65 76 65 6c 29 09 0a f9 32  test.(devel)...2                                                                                                   0x0040 43 31 86 18 20 72 00 82 42 10 41 16 d8 f2        C1.. r..B.A...
""..inittask SNOPTRDATA size=32                                                                                                                                                    0x0000 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  ................                                                                                                   0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................                                                                                                   rel 24+8 t=1 fmt..inittask+0                                                                                                                                       runtime.modinfo SDATA size=16                                                                                                                                                      0x0000 00 00 00 00 00 00 00 00 4e 00 00 00 00 00 00 00  ........N.......                                                                                                   rel 0+8 t=1 go.string."0w\xaf\f\x92t\b\x02A\xe1\xc1\a\xe6\xd6\x18\xe6path\tcommand-line-arguments\nmod\ttest\t(devel)\t\n\xf92C1\x86\x18 r\x00\x82B\x10A\x16\xd8\xf2"+0""..stmp_0 SRODATA size=16
        0x0000 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 00  ................
        rel 0+8 t=1 go.string."Hello World!"+0                                                                                                                             go.itab.*os.File,io.Writer SRODATA dupok size=32
    0x0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................                                                                                                   0x0010 44 b5 f3 33 00 00 00 00 00 00 00 00 00 00 00 00  D..3............                                                                                                       rel 0+8 t=1 type.io.Writer+0
        rel 8+8 t=1 type.*os.File+0                                                                                                                                                rel 24+8 t=1 os.(*File).Write+0                                                                                                                                    go.itablink.*os.File,io.Writer SRODATA dupok size=8
        0x0000 00 00 00 00 00 00 00 00                          ........
        rel 0+8 t=1 go.itab.*os.File,io.Writer+0                                                                                                                           type..importpath.fmt. SRODATA dupok size=6                                                                                                                                         0x0000 00 00 03 66 6d 74                                ...fmt                                                                                                     type..importpath.unsafe. SRODATA dupok size=9                                                                                                                                      0x0000 00 00 06 75 6e 73 61 66 65                       ...unsafe                                                                                                  gclocals·e6397a44f8e1b6e77d0f200b4fba5269 SRODATA dupok size=10                                                                                                                    0x0000 02 00 00 00 03 00 00 00 01 00                    ..........                                                                                                 gclocals·69c1753bd5f81501d95132d08af04464 SRODATA dupok size=8                                                                                                                     0x0000 02 00 00 00 00 00 00 00                          ........                                                                                                   gclocals·33cdeccccebe80329f1fdbee7f5874cb SRODATA dupok size=8                                                                                                                     0x0000 01 00 00 00 00 00 00 00                          ........
gclocals·f207267fbf96a0178e8758c6e3e0ce28 SRODATA dupok size=9
        0x0000 01 00 00 00 02 00 00 00 00                       .........
"".main.stkobj SRODATA size=24
        0x0000 01 00 00 00 00 00 00 00 f0 ff ff ff ff ff ff ff  ................
        0x0010 00 00 00 00 00 00 00 00                          ........
        rel 16+8 t=1 type.[1]interface {}+0

Golang 支持的指令集架构

  • amd64, arm64, mips64, ppc64

  • mips, arm, wasm, x86, s390x

Reference