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

时间:2014-09-24 15:47:44

标签: 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部分得到这些定义{1}}。

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

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

似乎构建了,链接了构造函数及其实现。

所以我的问题是:

  1. 这个构造函数/析构函数的实际内容是什么?

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

  3. 我转储了相关的.ctors.init_array部分,但我找不到定义_ZN8ComputerC1Ev_ZN8ComputerC2Ev之间关系的元数据...

1 个答案:

答案 0 :(得分:2)

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

  

.global 符号.globl 符号

     

.global使符号ld可见。如果你在你的中定义了符号   部分程序,其值可用于其他部分程序   与之相关的。否则, symbol 从a获取其属性   来自另一个文件的同名符号链接到同一个文件中   程序

     

.set 符号,表达式

     

symbol 的值设置为 expression 。这会更改符号的值和   键入以符合表达式

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

现在,您可能很想知道为什么构造函数有两个不同的名称(例如_ZN8ComputerC1Ev_ZN8ComputerC2Ev)。答案有点复杂,所以我会引用你的另一个问题来详细解决它:

Dual emission of constructor symbols