c++ - 为什么我们不编写可以处理C++标识符的汇编器和链接器?

标签 c++ assembly name-mangling symbol-table object-code

我对为什么使用名称修饰的理解是,汇编器和链接器只能处理C标识符。任何现有的汇编程序都不能将“int foo::bar::baz<spam::eggs>(const MoreSpam&)”用作标签,并且现有的链接程序也不会将其识别为有效的函数签名,因此它变成类似于“_ZN3foo3bar3bazIN4spam4eggsEEEiRK8MoreSpam”的形式,即(或多或少)有效的C标识符。
但这似乎是我们工具的相对琐碎的限制。有什么充分的理由为什么我们不能或不编写像这样的汇编器和链接器:

int foo::bar::baz<spam::eggs>(MoreSpam const&):
    ; opcodes go here
    ret
是可以的吗?

最佳答案

实际上,您可以在GNU汇编器中将int foo::bar::baz<spam::eggs>(const MoreSpam&)用作标识符,只需要在名称中加上引号即可:

"int foo::bar::baz<spam::eggs>(MoreSpam const&)":
        ret

$ as -o test.o test.s
$ nm test.o
0000000000000000 t int foo::bar::baz<spam::eggs>(MoreSpam const&)
$ ld test.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
$ nm a.out
0000000000402000 T __bss_start
0000000000402000 T _edata
0000000000402000 T _end
0000000000401000 t int foo::bar::baz<spam::eggs>(MoreSpam const&)
                 U _start
与此相关的一个问题是,除了在很多上下文中要处理带有空格和符号的符号之外,还很麻烦的是,并非所有C++错位标识符都可以明确表示一个C++源代码片段。相同的C++“符号”可以具有多个错误表示,某些错误符号没有C++表示。
例如,GNU C++编译器defines 5 different ways of mangling the name of the same constructor使用的Itanium C++ ABI取决于编译器生成的构造函数的哪种变体。同样,有三种不同的方式来处理给定析构函数的名称。符号_ZN3fooC1Ev_ZN3fooC2Ev都与foo::foo()分解,并且都可以存在于同一程序中。
当然,您可以发明新的类似于C++的语法来表示这些内容,但是您只是在发明更详细的符号修饰方式。
最后,也许C++编译器以它们的方式修改名称的最重要原因是它们可以与各种工具一起使用。尽管今天已经不那么普遍了,但是GNU C++编译器可以与GAS以外的其他汇编器一起使用。

关于c++ - 为什么我们不编写可以处理C++标识符的汇编器和链接器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62597471/

相关文章:

c++ - cvLoadImage 无法在使用 C 的 Xcode 中工作

c - 在 mmap 中执行代码以产生可执行代码段错误

c - 外壳代码 : access violation exception for no obvious reason

c++ - C++ 的 64 位名称修改

c - 如何覆盖每个符号 NASM 中的 `--prefix` 选项?

c++ - 模板转换运算符

c++ - itoa 和 uitoa 用法

c++ - 如果可能的话,如何使用可变参数模板来创建一个并排打印任何类型的多个 std::vector 的函数?

assembly - 如何简化引用自身作为参数的函数? (这是什么意思)

python - 对名称修改目的的总结正确吗?