我有兴趣检查标准Go编译器的x86汇编输出,以确定我的代码是否被转换成合理高效的汇编代码; 通过分析和检查汇编输出,希望能够了解应该在哪里/如何重写我的Go代码以获得最佳性能。但是当我使用-S标志检查代码时,Go输出了一堆乱七八糟的东西!我想要两件事:
有没有办法让Go编译器将汇编输出转储到文件中,而不仅仅是在终端上打印出来?
此外,有没有办法使Go编译器将汇编代码分离成单独的带有标签的函数?我知道一些函数可能会被内联,因此不会出现在汇编代码中。我现在看到的只是一堆难以理解的同质汇编代码块。
您可以像这样将输出重定向到文件:
go tool compile -S file.go > file.s
你可以使用-N选项禁用优化:
go tool compile -S -N file.go
或者,您也可以使用gccgo:
gccgo -S -O0 -masm=intel test.go
这将生成test.s文件。您可以尝试使用-O0/1/2/3选项,以观察不同的优化效果。
go build -gcflags -S test.go > test.s
也应该可以工作(根据 https://golang.org/doc/asm) - rkusago1.5
起,使用命令 go tool compile -S file.go > file.S
可以将 Go 代码转换为汇编代码并输出到文件 file.S
中。 - Ivan Black我不建议使用-S
的输出结果,因为Go链接器可能会对目标代码进行大量更改。但是它确实可以让你了解发生了什么。
Go汇编器的输出结果也相当非标准化。
当我想要这样做时,我总是使用objdump,这将给您一个漂亮的标准汇编器输出结果。
例如对于x86 / amd64处理器:
objdump -d executable > disassembly
对于ARM(为了让寄存器名称与Go使用的相同)
objdump -M reg-names-raw -d executable > disassembly
mov %r11b,0x84(%rsp,%r10,1)
。只是说一下。 - undefined在生成的可执行文件上运行 go tool objdump
。
使用其 -s
选项将输出限制为感兴趣的函数。
将输出转储到文件中:
go tool objdump EXECUTABLE_FILE > ASSEMBLY_FILE
如果您想要包含源Go代码(假设您拥有一个可用的golang设置,并且已经自行构建了可执行文件):
go tool objdump -S EXECUTABLE_FILE
less
时使用-R
开关(或通过将其添加到环境中,例如在.bashrc
中:export LESS="$LESS -R"
)。go-objdump EXECUTABLE_FILE | less -R
另外,有一个名为godbolt.org的网站,它可能具有最易读的输出,并且允许您轻松切换编译器(gc、gccgo)和版本。
loov/lensm
,它可以查看汇编和源代码。To run the program, provide a regular expression filter for the symbol you want to inspect.
-watch
allows to automatically reload the executable and information when it changes.lensm -watch -filter Fibonacci lensm
Note: The program requires a binary that is built on your computer, otherwise the source code for the functions cannot be loaded.
Result:
package main
func main() {
println(3)
}
产生:
--- prog list "main" ---
0000 (x.go:3) TEXT main+0(SB),$8-0
0001 (x.go:3) FUNCDATA $0,gcargs·0+0(SB)
0002 (x.go:3) FUNCDATA $1,gclocals·0+0(SB)
0003 (x.go:4) MOVQ $3,(SP)
0004 (x.go:4) PCDATA $0,$8
0005 (x.go:4) CALL ,runtime.printint+0(SB)
0006 (x.go:4) PCDATA $0,$-1
0007 (x.go:4) PCDATA $0,$0
0008 (x.go:4) CALL ,runtime.printnl+0(SB)
0009 (x.go:4) PCDATA $0,$-1
0010 (x.go:5) RET ,
go tool compile -S hello.go > hello.s
这样就得到了我想要的结果!
>
或其他命令 shell 支持的符号将命令的输出重定向到文件中怎么样? - Michael