我对gcc程序集非常熟悉...最近我被迫使用g ++进行代码清理。让我提一下我对汇编非常熟悉,因此出于好奇,我经常看看编译器生成的asm有多好。
但是使用g ++的命名约定只是奇怪的。我想知道是否有关于如何读取其asm输出的指南?
非常感谢。
答案 0 :(得分:24)
我没有发现g ++的'丑陋'或难以理解,尽管我已经与GCC合作了8年多了。
在Linux上,函数标签通常是_ZN,“_ ZN”前缀是指定C ++名称修改(而不是C)的标记,后跟函数所属的命名空间,然后是函数名和参数类型,然后是模板,如果有的话。
示例:
// tests::vec4::testEquality() _ZN5tests4vec412testEqualityEv _ZN - C++ mangling, 'N' for member (_ZZ for const or others) 5tests - length (5 chars) + name 4vec4 -length (4 chars) + sub namespace 12testEquality - length (12 chars) + function name Ev - void argument (none)
答案 1 :(得分:18)
来自 man g++
:
-fverbose-asm
在生成的汇编代码中添加额外的注释信息以使其更多 可读。此选项通常仅用于那些实际需要阅读的人 生成汇编代码(可能在调试编译器本身时)。
答案 2 :(得分:12)
如果您正在查看外部符号的命名约定,那么这将遵循您正在使用的平台的名称修改约定。它可以通过c++filt
程序反转,该程序将为您提供C ++函数名的人类可读版本,尽管它们(很可能)将不再是有效的链接器符号。
如果您只是查看本地功能标签,那么您运气不好。 g++
的汇编程序输出用于与汇编程序进行通信,而不是为了便于人类理解而设计。它将产生一组相对无意义的标签。
答案 3 :(得分:5)
如果代码包含调试信息,objdump
可以提供更有用的反汇编:
-S, --source Intermix source code with disassembly
-l, --line-numbers Include line numbers and filenames in output
答案 4 :(得分:0)
对于正在努力在程序中分解这些名称的人(如我),希望this thread会有所帮助。
def demangle(name):
import subprocess as sp
stdout, _ = sp.Popen(['c++filt', name],
stdin=sp.PIPE, stdout=sp.PIPE).communicate()
return stdout.split("\n")[0]
print demangle('_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE17_M_stringbuf_initESt13_Ios_Openmode')