c++ - 为什么在 g++ 生成的汇编代码中这样定义构造函数/析构函数?

标签 c++ assembly elf

我写了一个简单的 C++ 程序,用它定义了一个如下所示的类:

#include <iostream>

using namespace std;

class Computer
{
public:
  Computer();
  ~Computer();
};

Computer::Computer()
{
}

Computer::~Computer()
{
}

int main()
{
  Computer compute;  
    return 0;
}

当我使用 g++(测试是在 x86 32 位 Linux 和 g++ 4.6.3 上进行的。)生成 ctorsdtors 时,我在 .ctors 部分的末尾获取这些定义。

    .globl  _ZN8ComputerC1Ev
    .set    _ZN8ComputerC1Ev,_ZN8ComputerC2Ev
    .globl  _ZN8ComputerD1Ev
    .set    _ZN8ComputerD1Ev,_ZN8ComputerD2Ev

在深入研究生成的汇编代码后,我发现 _ZN8ComputerC1Ev 应该是构造类 Computer 时使用的函数名称,而 _ZN8ComputerC2Ev 是类 Computer 的构造函数的名称。同样的事情发生在 Computer 的析构函数声明和调用中。

似乎建立了一个,将构造函数和它的实现联系起来。

所以我的问题是:

  1. 这个构造函数/析构函数信息到底有什么用?

  2. 我在哪里可以找到它们的 ELF 格式?

我转储了相关的 .ctors.init_array 部分,但我找不到定义 _ZN8ComputerC1Ev_ZN8ComputerC2Ev...

最佳答案

这里没有 table 。 .globl.set 是所谓的汇编程序指令伪操作。它们向汇编程序发出信号,但不一定会产生实际代码或数据。来自 the docs :

.global symbol, .globl symbol

.global makes the symbol visible to ld. If you define symbol in your partial program, its value is made available to other partial programs that are linked with it. Otherwise, symbol takes its attributes from a symbol of the same name from another file linked into the same program.

.set symbol, expression

Set the value of symbol to expression. This changes symbol's value and type to conform to expression.

所以你引用的片段只是确保构造函数可用于链接,以防它被其他编译单元引用。您通常在最终 ELF 中看到的唯一效果是符号表中存在这些符号(如果它没有被剥离)。

现在,您可能很好奇为什么构造函数有两个不同的名称(例如 _ZN8ComputerC1Ev_ZN8ComputerC2Ev)。答案有点复杂,所以我将向您介绍另一个 SO 问题,该问题详细解决了这个问题:

Dual emission of constructor symbols

关于c++ - 为什么在 g++ 生成的汇编代码中这样定义构造函数/析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26021243/

相关文章:

assembly - 由 gcc : What happens from entry point to main? 编译的 ELF 二进制文件

c++ - 清除内存块(或 SDL 表面)的最快方法是什么?

linux - 全局偏移表结构

linux - 为什么 Linux 二进制文件的虚拟内存地址从 0x8048000 开始?

c++ - 如何访问 3D CV::Mat 的索引

C++ : forward declaring const with internal linkage

C++ std::string 初始化性能更好(汇编)

assembly - 了解 x86 MOV 语法

c - GCC 在编译/链接期间确定的符号的值

c++ - GCC `-fsanitize=bounds` `std::array` 的奇怪行为