g ++生成的程序集看起来很难看

时间:2009-07-19 20:05:17

标签: c++ assembly g++

我对gcc程序集非常熟悉...最近我被迫使用g ++进行代码清理。让我提一下我对汇编非常熟悉,因此出于好奇,我经常看看编译器生成的asm有多好。

但是使用g ++的命名约定只是奇怪的。我想知道是否有关于如何读取其asm输出的指南?

非常感谢。

5 个答案:

答案 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')