c++类反汇编

c++ class disassembly

本文关键字:反汇编 c++      更新时间:2023-10-16

我有以下代码:

class Base {
public:
int x,y;
Base() { x=10; y=20; }
virtual void myfunction() { }
};
int main() {
Base *b = new Base();
return 0;
}

拆解给了我类似的东西:

push 0Ch                ; size of Base
call j_<some giberrish> ; IDA gives the comment "operator new(uint)"
add esp, 4              ; function epilogue
mov [ebp+var_E0], eax

几行之后,将调用构造函数。

mov ecx, [ebp+var_E0]
call j_Base__Base
mov [ebp+var_F4], eax
  • 起初,我认为var_E0会包含指向实例的指针,但现在我非常确信var_F4会包含构造函数的返回值
  • 在这种情况下,var_E0包含什么?为什么在调用构造函数之前将其移动到ecx

它是编译器生成的临时内部变量。

编写new Base时,编译器会生成对全局operator new函数,然后在返回的住址显然,您的编译器保存了从operator new存储在内存中,而不是将其保存在寄存器中。

Visual C++使用内部约定,其中构造函数返回指向对象实例的指针(根据C++标准,构造函数没有返回值)。因此,在您的情况下,var_E0var_F4都持有实例指针。

有关Visual C++如何实现C++的更多详细信息,请查看我的文章。

这几乎可以肯定是您正在查看的调试构建,并且调试构建的功能非常保守。创建对象需要两个阶段:分配内存,然后构造对象。编译器正在将分配的内存指针放入一个临时变量中。如果您构建了一个优化版本,则不会存储此临时变量,因为这会带来不必要的开销(写入/读取RAM)。