【问题标题】:Why don't we write assemblers and linkers that can handle C++ identifiers?为什么我们不编写可以处理 C++ 标识符的汇编器和链接器呢?
【发布时间】:2020-10-17 05:11:50
【问题描述】:

我对我们为什么使用名称修饰的理解是汇编器和链接器只能处理 C 标识符。 “int foo::bar::baz<spam::eggs>(const MoreSpam&)”不能被任何现有的汇编器用作标签,并且现有的链接器不会将其识别为有效的函数签名,因此它变成了类似于“_ZN3foo3bar3bazIN4spam4eggsEEEiRK8MoreSpam”的东西,即(或多或少)一个有效的 C 标识符。

但这似乎是我们工具的一个相对微不足道的限制。我们不能或不编写汇编器和链接器有什么充分的理由,其中有这样的东西:

int foo::bar::baz<spam::eggs>(MoreSpam const&):
    ; opcodes go here
    ret

是否允许?

【问题讨论】:

  • 在一天结束的时候,你可以做任何你想做的事(TI 和 Weird Al 版本都将被接受),但必须有人坐下来做这项工作。
  • 汇编器必须匹配工具。不同的系统会以不同的方式进行处理。
  • 嗯,不确定我是否完全理解您的问题?如果我声明int foo::bar::baz&lt;spam::eggs&gt;(MoreSpam const&amp;),我需要能够从 C 上下文中调用它。您会使用哪种语法(在 C 中)?
  • Go 就像你说的那样,如果你正确地转义符号名称,你可以使用 UNIX 汇编器为你的符号命名。名称修改的要点是,有足够多的汇编程序不支持奇怪命名的符号,因此使用更常见的符号名称可以更容易地在汇编程序能力较差的平台上实现 C++。
  • 对于汇编程序,如果您知道符号名称是没有空格的字符串,并且由不包含可能与其他语法元素混淆的字符的字符集构建,则解析会更容易。考虑像@​​987654325@ 这样的行。逗号不再总是分隔两个指令操作数,&amp; 可能并不总是按位与运算符。您的汇编器现在需要能够解析任意 C++ 类型语法,这比典型的汇编器解析器需要的要复杂得多。

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


【解决方案1】:

您实际上可以使用int foo::bar::baz&lt;spam::eggs&gt;(const MoreSpam&amp;) 作为 GNU 汇编器的标识符,您只需将名称放在引号中:

"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 以外的汇编器一起使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-16
    • 2021-06-27
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多