Assembly 易读的Golang汇编输出?
我感兴趣的是检查标准Go编译器的x86汇编输出,看看我的代码是否真的被转换为合理高效的汇编代码;希望通过分析和检查程序集输出,我可以得到一条线索,知道应该在哪里/如何重写Go代码以获得最佳性能。但是,当我使用-S标志检查代码时,Go会吐出一团乱麻!我想要两样东西:Assembly 易读的Golang汇编输出?,assembly,go,Assembly,Go,我感兴趣的是检查标准Go编译器的x86汇编输出,看看我的代码是否真的被转换为合理高效的汇编代码;希望通过分析和检查程序集输出,我可以得到一条线索,知道应该在哪里/如何重写Go代码以获得最佳性能。但是,当我使用-S标志检查代码时,Go会吐出一团乱麻!我想要两样东西: 有没有办法让Go编译器将程序集输出转储到一个文件中,而不仅仅是在终端上打印出来 还有,有没有办法让Go编译器将汇编代码分离成带标签的单独函数?我知道有些函数可能是内联的,因此不会出现在汇编代码中。我所看到的只是一个几乎不可能理解的同质
go tool compile -S file.go > file.s
go tool compile -S -N file.go
gccgo -S -O0 -masm=intel test.go
这将生成test.s。您可以使用-O0/1/2/3来查看不同的优化。我不建议使用
-S
的输出,因为Go链接器可以大量更改写入目标代码的内容。它确实让你对正在发生的事情有所了解
go汇编程序的输出也是相当非标准的
当我想这样做时,我总是使用它,这将给你一个很好的标准汇编输出
用于x86/amd64的Eg
objdump -d executable > disassembly
对于ARM(使寄存器名称与Go使用的相同)
在生成的可执行文件上运行
go-tool-objdump
要将输出限制为有趣的函数,请使用其
-s
选项。我对其他答案有疑问,因为生成的程序集提供了比我想要的多得多的信息,但仍然没有足够的细节。让我解释一下:它为go内部导入的所有库提供了程序集,但没有提供代码所在的行(我的代码都在文件的底部)
以下是我从官方文件中发现的:
$GOOS=linux-GOARCH=amd64-go-tool-compile-S x.go\or:go-build-gcflags-S x.go
文件:
产生:
--- 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工具编译-S hello.go>hello.S
它得到了我想要的结果 要将输出转储到文件:
go tool objdump EXECUTABLE_FILE > ASSEMBLY_FILE
如果您希望包含源Go代码(假设您有一个工作的golang设置,并且您自己构建了可执行文件):
为了使输出更易于查看,我使用了生成以下内容的a(简而言之,它将更改控制流的指令着色-蓝色表示跳转,绿色表示调用/返回,红色表示陷阱,紫色表示填充-并在无条件控制流跳转后添加新行):
如果您使用上面的包装器,则在管道连接到less
时,您可能希望使用-R
开关(或通过将其添加到环境中,例如在.bashrc
中):导出less=“$less-R”
):
或者,有一个可能是可读性最强的输出,允许您在编译器(gc、gccgo)和版本之间轻松切换。我发现Mac用户使用XCode开发工具的最简单方法是使用
otool
$ otool -tV myGoProgramBinary to disassemble
1)使用
或命令shell支持的任何东西将命令输出重定向到文件怎么样?此外,通过查看汇编代码进行分析的方法可能不是最有效的方法。你看过Go代码可用的分析工具了吗?(例如)我同意你的看法,装配输出需要一些改进。问题是Go编译器不生成实际的程序集。它生成的东西看起来很像程序集,但包含大量伪指令,这些伪指令将由链接器扩展。只有在链接完成后,才会产生实际的装配(并立即装配)。另外,请查看。Go的参考实现使用了这个assembler.PS:我正在寻找类似于GCC命令的东西:-fverbose asmGo build-gcflags-S test.Go>test.S
也应该工作(根据)go tool comile-S file.go>file.S
因为go1.5
@IvanBlack您的评论应该得到顶级响应。您可能会发现Godbolt编译器资源管理器对于颜色高亮显示非常有用,可以将源代码行映射到asm。具有gc1.10.1和gccgo 7.2的简单函数输出。这是一个非常好的工具
go tool objdump EXECUTABLE_FILE > ASSEMBLY_FILE
go tool objdump -S EXECUTABLE_FILE
go-objdump EXECUTABLE_FILE | less -R
$ otool -tV myGoProgramBinary to disassemble