关闭

从逆向分析角度看C++拷贝构造函数

发表于:2013-3-19 09:47

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Maxwell_    来源:51Testing软件测试网采编

  一段C++代码:

//: HowMany_2.cpp
#include <iostream>

using namespace std;

class HowMany {
  static int objectCount;
 
public:
  HowMany() {
    ++objectCount;
    print("HowMany()");
  }
  ~HowMany() {
    --objectCount;
    print("~HowMany()");
  }
  HowMany(const HowMany& h) {
    ++objectCount;
    print("HowMany(const HowMany&)");
  }
 
  void print(const char ss[]) {
    cout << ss << ": ";
    cout << "objectCount = " << objectCount << endl;
    return ;
  }
};

int HowMany::objectCount = 0;

HowMany f(HowMany x) {
  x.print("x argument inside f()");
  cout << "Return From f()" << endl;
  return x;  // 有返回值 x
}

int main() {
  {
    HowMany h;
    cout << "Entering f()" << endl;
    HowMany h2 = f(h);
  }
  return 0;
} ///:~

  运行结果:

  Assembly Code:

38:   int main() {
39:     {
40:       HowMany h;
004017FD   lea         ecx,[h]     ; [h] 为对象 h 的内存地址
00401800   call        @ILT+685(HowMany::HowMany) (004012b2) ; 调用构造函数
00401805   mov         dword ptr [ebp-4],0
41:       cout << "Entering f()" << endl;
0040180C   push        offset @ILT+200(std::endl) (004010cd)
00401811   push        offset string "Entering f()" (0046f090)
00401816   push        offset std::cout (0047ce98)
0040181B   call        @ILT+660(std::operator<<) (00401299) ; 题外话,观察一下进栈顺序
00401820   add         esp,8
00401823   mov         ecx,eax
00401825   call        @ILT+480(std::basic_ostream<char,std::char_traits<char> >::operator<<) (004011e5)
42:       HowMany h2 = f(h);
0040182A   push        ecx
0040182B   mov         ecx,esp     ; 当前 ESP 所指的栈块作为临时对象Temp的内存地址
0040182D   mov         dword ptr [ebp-18h],esp
00401830   lea         eax,[h]     
00401833   push        eax     ; 将h的内存地址[h]压入堆栈
00401834   call        @ILT+0(HowMany::HowMany) (00401005) ; 调用拷贝构造函数,把h的内容拷贝到Temp的内存中
00401839   mov         dword ptr [ebp-1Ch],eax
0040183C   lea         ecx,[h2] 
0040183F   push        ecx     ; 将h2的内存地址[h2]压入堆栈
00401840   call        @ILT+640(f) (00401285)   ; 调用f()函数
00401845   add         esp,8
00401848   mov         dword ptr [ebp-20h],eax
43:     }
0040184B   lea         ecx,[h2]
0040184E   call        @ILT+500(HowMany::~HowMany) (004011f9) ; 调用析构函数,销毁h2
00401853   mov         dword ptr [ebp-4],0FFFFFFFFh
0040185A   lea         ecx,[h]
0040185D   call        @ILT+500(HowMany::~HowMany) (004011f9) ; 调用析构函数,销毁h
44:     // getchar();
45:     return 0;
00401862   xor         eax,eax
46:   } ///:~

41/41234>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号