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

问题描述 投票:9回答:5

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

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

非常感谢。

c++ assembly g++
5个回答
24
投票

虽然我已经和GCC合作了8年多,但我并没有发现g ++的'丑陋'或者难以理解。

在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)

18
投票

来自man g++

-fverbose-ASM 在生成的汇编代码中添加额外的注释信息,以使其更具可读性。此选项通常仅用于那些实际需要读取生成的汇编代码的人(可能在调试编译器本身时)。


12
投票

如果您正在查看外部符号的命名约定,那么这将遵循您正在使用的平台的名称修改约定。它可以通过c++filt程序反转,它将为您提供C ++函数名的人类可读版本,尽管它们(很可能)将不再是有效的链接器符号。

如果您只是查看本地功能标签,那么您运气不好。 g++的汇编程序输出用于与汇编程序进行通信,而不是为了便于人类理解而设计。它会产生一组相对无意义的标签。


5
投票

如果代码有调试信息,objdump可以提供更有用的反汇编:

-S, --source             Intermix source code with disassembly
-l, --line-numbers             Include line numbers and filenames in output

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')
© www.soinside.com 2019 - 2024. All rights reserved.