【问题标题】:Why constructor/destructor are defined like this in g++ produced assembly code?为什么在 g++ 生成的汇编代码中这样定义构造函数/析构函数?
【发布时间】:2014-09-26 03:54:25
【问题描述】:

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

#include <iostream>

using namespace std;

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

Computer::Computer()
{
}

Computer::~Computer()
{
}

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

当我使用g++(Test is on x86 32bit Linux with 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 之间关系的元数据...

【问题讨论】:

    标签: c++ assembly elf


    【解决方案1】:

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

    .global符号.globl符号

    .global 使 symbolld 可见。如果您在您的 部分程序,其值可用于其他部分程序 与它相关的。否则,symbol 从一个 来自另一个文件的同名符号链接到相同的 程序。

    .set符号、表达式

    symbol的值设置为expression。这会改变 symbol 的值和 类型符合表达式

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

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

    Dual emission of constructor symbols

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 2015-02-10
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      相关资源
      最近更新 更多