c++ 反汇编 构造函数和析构函数
构造函数和析构函数出现的时机
- 局部对象
109: // 局部对象定义调用构造函数
110:
111: CNumber Number;
00C8A37D 8D 4D EC lea ecx,[Number]
00C8A380 E8 14 97 FF FF call CNumber::CNumber (0C83A99h)
局部对象的析构顺序与构造顺序相反
- 堆对象
109: // 局部对象定义调用构造函数
110:
111: CNumber Number;
00C8A385 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
112: // 申请堆对象
113: CNumber * pNumber = NULL;
00C8A38C C7 45 E0 00 00 00 00 mov dword ptr [pNumber],0
114: pNumber = new CNumber;
00C8A393 6A 04 push 4
00C8A395 E8 31 92 FF FF call operator new (0C835CBh) //运算符 new
00C8A39A 83 C4 04 add esp,4
00C8A39D 89 85 F0 FE FF FF mov dword ptr [ebp-110h],eax
00C8A3A3 C6 45 FC 01 mov byte ptr [ebp-4],1
00C8A3A7 83 BD F0 FE FF FF 00 cmp dword ptr [ebp-110h],0 //new返回的堆空间地址
00C8A3AE 74 13 je main+83h (0C8A3C3h) //为NULL则跳过构造函数
00C8A3B0 8B 8D F0 FE FF FF mov ecx,dword ptr [ebp-110h]
00C8A3B6 E8 DE 96 FF FF call CNumber::CNumber (0C83A99h) //构造函数
00C8A3BB 89 85 A0 FE FF FF mov dword ptr [ebp-160h],eax
00C8A3C1 EB 0A jmp main+8Dh (0C8A3CDh)
00C8A3C3 C7 85 A0 FE FF FF 00 00 00 00 mov dword ptr [ebp-160h],0
00C8A3CD 8B 85 A0 FE FF FF mov eax,dword ptr [ebp-160h]
00C8A3D3 89 85 FC FE FF FF mov dword ptr [ebp-104h],eax
00C8A3D9 C6 45 FC 00 mov byte ptr [ebp-4],0
00C8A3DD 8B 8D FC FE FF FF mov ecx,dword ptr [ebp-104h]
00C8A3E3 89 4D E0 mov dword ptr [pNumber],ecx
115: pNumber->m_nNumber = 2;
00C8A3E6 8B 45 E0 mov eax,dword ptr [pNumber]
00C8A3E9 C7 00 02 00 00 00 mov dword ptr [eax],2
116: printf("%d \r\n", pNumber->m_nNumber);
00C8A3EF 8B 45 E0 mov eax,dword ptr [pNumber]
00C8A3F2 8B 08 mov ecx,dword ptr [eax]
00C8A3F4 51 push ecx
00C8A3F5 68 78 5F D2 00 push offset string "%d \r\n" (0D25F78h)
00C8A3FA E8 C6 6F FF FF call _printf (0C813C5h)
00C8A3FF 83 C4 08 add esp,8
117:
118: if (pNumber != NULL)
00C8A402 83 7D E0 00 cmp dword ptr [pNumber],0
00C8A406 74 44 je main+10Ch (0C8A44Ch)
119: {
120: delete pNumber;
00C8A408 8B 45 E0 mov eax,dword ptr [pNumber]
00C8A40B 89 85 D8 FE FF FF mov dword ptr [ebp-128h],eax
00C8A411 8B 8D D8 FE FF FF mov ecx,dword ptr [ebp-128h]
00C8A417 89 8D E4 FE FF FF mov dword ptr [ebp-11Ch],ecx
00C8A41D 83 BD E4 FE FF FF 00 cmp dword ptr [ebp-11Ch],0
00C8A424 74 15 je main+0FBh (0C8A43Bh)
00C8A426 6A 01 push 1
00C8A428 8B 8D E4 FE FF FF mov ecx,dword ptr [ebp-11Ch]
00C8A42E E8 27 80 FF FF call CNumber::`scalar deleting destructor' (0C8245Ah)
00C8A433 89 85 A0 FE FF FF mov dword ptr [ebp-160h],eax
00C8A439 EB 0A jmp main+105h (0C8A445h)
00C8A43B C7 85 A0 FE FF FF 00 00 00 00 mov dword ptr [ebp-160h],0
121: pNumber = NULL;
00C8A445 C7 45 E0 00 00 00 00 mov dword ptr [pNumber],0
122: }
释放堆对象数组
125: // 释放多个堆对象
126: CNumber * pArray = new CNumber[2];
00C8A44C 6A 0C push 0Ch
122: }
123:
124:
125: // 释放多个堆对象
126: CNumber * pArray = new CNumber[2];
00C8A44E E8 0D 75 FF FF call operator new[] (0C81960h)
00C8A453 83 C4 04 add esp,4
00C8A456 89 85 C0 FE FF FF mov dword ptr [ebp-140h],eax
00C8A45C C6 45 FC 02 mov byte ptr [ebp-4],2
00C8A460 83 BD C0 FE FF FF 00 cmp dword ptr [ebp-140h],0
00C8A467 74 3A je main+163h (0C8A4A3h)
00C8A469 8B 85 C0 FE FF FF mov eax,dword ptr [ebp-140h]
00C8A46F C7 00 02 00 00 00 mov dword ptr [eax],2
00C8A475 68 9E 2B C8 00 push offset CNumber::~CNumber (0C82B9Eh)
00C8A47A 68 99 3A C8 00 push offset CNumber::CNumber (0C83A99h)
00C8A47F 6A 02 push 2
00C8A481 6A 04 push 4
00C8A483 8B 8D C0 FE FF FF mov ecx,dword ptr [ebp-140h]
00C8A489 83 C1 04 add ecx,4
00C8A48C 51 push ecx
00C8A48D E8 11 73 FF FF call `eh vector constructor iterator' (0C817A3h)
00C8A492 8B 95 C0 FE FF FF mov edx,dword ptr [ebp-140h]
00C8A498 83 C2 04 add edx,4
00C8A49B 89 95 A0 FE FF FF mov dword ptr [ebp-160h],edx
00C8A4A1 EB 0A jmp main+16Dh (0C8A4ADh)
00C8A4A3 C7 85 A0 FE FF FF 00 00 00 00 mov dword ptr [ebp-160h],0
00C8A4AD 8B 85 A0 FE FF FF mov eax,dword ptr [ebp-160h]
00C8A4B3 89 85 CC FE FF FF mov dword ptr [ebp-134h],eax
00C8A4B9 C6 45 FC 00 mov byte ptr [ebp-4],0
00C8A4BD 8B 8D CC FE FF FF mov ecx,dword ptr [ebp-134h]
00C8A4C3 89 4D D4 mov dword ptr [pArray],ecx
127: if (pArray != NULL)
00C8A4C6 83 7D D4 00 cmp dword ptr [pArray],0
00C8A4CA 74 44 je main+1D0h (0C8A510h)
128: {
129: delete [] pArray;
00C8A4CC 8B 45 D4 mov eax,dword ptr [pArray]
00C8A4CF 89 85 A8 FE FF FF mov dword ptr [ebp-158h],eax
00C8A4D5 8B 8D A8 FE FF FF mov ecx,dword ptr [ebp-158h]
00C8A4DB 89 8D B4 FE FF FF mov dword ptr [ebp-14Ch],ecx
00C8A4E1 83 BD B4 FE FF FF 00 cmp dword ptr [ebp-14Ch],0
00C8A4E8 74 15 je main+1BFh (0C8A4FFh)
00C8A4EA 6A 03 push 3
00C8A4EC 8B 8D B4 FE FF FF mov ecx,dword ptr [ebp-14Ch]
00C8A4F2 E8 B7 8A FF FF call CNumber::`vector deleting destructor' (0C82FAEh)
00C8A4F7 89 85 A0 FE FF FF mov dword ptr [ebp-160h],eax
00C8A4FD EB 0A jmp main+1C9h (0C8A509h)
00C8A4FF C7 85 A0 FE FF FF 00 00 00 00 mov dword ptr [ebp-160h],0
130: pArray = NULL;
00C8A509 C7 45 D4 00 00 00 00 mov dword ptr [pArray],0
131: }
- 参数对象
143: Show(MyString);
002CA529 51 push ecx //开辟4字节参数对象空间
002CA52A 8B CC mov ecx,esp
002CA52C 89 A5 90 FE FF FF mov dword ptr [ebp-170h],esp
002CA532 8D 45 C8 lea eax,[MyString]
002CA535 50 push eax
002CA536 E8 48 74 FF FF call CMyString::CMyString (02C1983h) //调用拷贝构造函数,将实参拷贝到开辟的参数对象空间中去。
002CA53B E8 DB 90 FF FF call Show (02C361Bh)
002CA540 83 C4 04 add esp,4
参数对象的析构函数
64: void Show(CMyString MyString){
002CA230 55 push ebp
002CA231 8B EC mov ebp,esp
002CA233 81 EC C0 00 00 00 sub esp,0C0h
002CA239 53 push ebx
002CA23A 56 push esi
002CA23B 57 push edi
002CA23C 8D BD 40 FF FF FF lea edi,[ebp-0C0h]
002CA242 B9 30 00 00 00 mov ecx,30h
002CA247 B8 CC CC CC CC mov eax,0CCCCCCCCh
002CA24C F3 AB rep stos dword ptr es:[edi]
65: printf(MyString.m_pString);
002CA24E 8B 45 08 mov eax,dword ptr [MyString]
002CA251 50 push eax
002CA252 E8 6E 71 FF FF call _printf (02C13C5h)
002CA257 83 C4 04 add esp,4
66: }
002CA25A 8D 4D 08 lea ecx,[MyString]
002CA25D E8 A1 88 FF FF call CMyString::~CMyString (02C2B03h) //在函数内,将进入函数前拷贝构造的参数对象析构。
002CA262 5F pop edi
002CA263 5E pop esi
002CA264 5B pop ebx
002CA265 81 C4 C0 00 00 00 add esp,0C0h
002CA26B 3B EC cmp ebp,esp
002CA26D E8 74 8C FF FF call __RTC_CheckEsp (02C2EE6h)
002CA272 8B E5 mov esp,ebp
002CA274 5D pop ebp
002CA275 C3 ret
- 返回对象
145: // 返回值为对象类型的拷贝构造使用
146: CMyString MyString1 = GetMyString();
002CA543 8D 45 BC lea eax,[MyString1]
002CA546 50 push eax
002CA547 E8 32 97 FF FF call GetMyString (02C3C7Eh)
002CA54C 83 C4 04 add esp,4
在返回对象的函数GetMyString内部,会调用拷贝函数,将函数内的局部对象拷贝到进入函数前准备的地址空间中。之后调用析构函数,释放函数内产生的局部对象。
68: // 返回对象
69: CMyString GetMyString()
70: {
002C9F40 55 push ebp
002C9F41 8B EC mov ebp,esp
002C9F43 6A FF push 0FFFFFFFFh
002C9F45 68 38 2B 36 00 push 362B38h
002C9F4A 64 A1 00 00 00 00 mov eax,dword ptr fs:[00000000h]
002C9F50 50 push eax
002C9F51 81 EC D8 00 00 00 sub esp,0D8h
002C9F57 53 push ebx
002C9F58 56 push esi
002C9F59 57 push edi
002C9F5A 8D BD 1C FF FF FF lea edi,[ebp-0E4h]
002C9F60 B9 36 00 00 00 mov ecx,36h
002C9F65 B8 CC CC CC CC mov eax,0CCCCCCCCh
002C9F6A F3 AB rep stos dword ptr es:[edi]
002C9F6C A1 08 A0 38 00 mov eax,dword ptr [__security_cookie (038A008h)]
002C9F71 33 C5 xor eax,ebp
002C9F73 50 push eax
002C9F74 8D 45 F4 lea eax,[ebp-0Ch]
002C9F77 64 A3 00 00 00 00 mov dword ptr fs:[00000000h],eax
002C9F7D C7 85 20 FF FF FF 00 00 00 00 mov dword ptr [ebp-0E0h],0
71: CMyString MyString;
002C9F87 8D 4D EC lea ecx,[MyString]
002C9F8A E8 74 7C FF FF call CMyString::CMyString (02C1C03h)//局部对象,构造函数
002C9F8F C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
72: MyString.SetString("World");
002C9F96 68 70 5F 36 00 push offset string "World" (0365F70h)
002C9F9B 8D 4D EC lea ecx,[MyString]
002C9F9E E8 44 98 FF FF call CMyString::SetString (02C37E7h)
73: return MyString;
002C9FA3 8D 45 EC lea eax,[MyString]
002C9FA6 50 push eax
002C9FA7 8B 4D 08 mov ecx,dword ptr [ebp+8]
002C9FAA E8 D4 79 FF FF call CMyString::CMyString (02C1983h)//调用拷贝构造函数
002C9FAF 8B 8D 20 FF FF FF mov ecx,dword ptr [ebp-0E0h]
002C9FB5 83 C9 01 or ecx,1
002C9FB8 89 8D 20 FF FF FF mov dword ptr [ebp-0E0h],ecx
002C9FBE C7 45 FC FF FF FF FF mov dword ptr [ebp-4],0FFFFFFFFh
002C9FC5 8D 4D EC lea ecx,[MyString]
002C9FC8 E8 36 8B FF FF call CMyString::~CMyString (02C2B03h) //函数内的局部对象 析构函数
002C9FCD 8B 45 08 mov eax,dword ptr [ebp+8]
74: }
- 全局对象
全局对象的构造函数在启动函数中调用。析构函数在main函数退出时调用。
- 静态对象
静态对象构造函数与析构函数调用的时机相同。
c++ 反汇编 构造函数和析构函数的更多相关文章
- 内存的分配VS回收&构造函数VS析构函数
之前有一个问题一直困扰着我,就是一个变量出了作用域,我以为这个变量的内存就被回收了,其实不是这样的,昨天问了一个高手,才豁然开朗,自己在看相关代码的反汇编代码,才知道原来真是这样就.这个问题,我想简单 ...
- .NET 基础 一步步 一幕幕[面向对象之构造函数、析构函数]
构造函数.析构函数 构造函数: 语法: //无参的构造函数 [访问修饰符] 函数名() :函数名必须与类名相同. //有参的构造函数 [访问修饰符] 函数名(参数列表):函数名必须与类名相同. 作用: ...
- 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成员)
[源码下载] 不可或缺 Windows Native (21) - C++: 继承, 组合, 派生类的构造函数和析构函数, 基类与派生类的转换, 子对象的实例化, 基类成员的隐藏(派生类成员覆盖基类成 ...
- C++构造函数、析构函数与抛出异常
[本文链接] http://www.cnblogs.com/hellogiser/p/constructor-destructor-exceptions.html [问题] 构造函数可以抛出异常么?析 ...
- python中的构造函数和析构函数
python中的特殊方法,其中两个,构造函数和析构函数的作用: 比说“__init__”这个构造函数,具有初始化的作用,也就是当该类被实例化的时候就会执行该函数.那么我们就可以把要先初始化的属性放到这 ...
- C++C++中构造函数与析构函数的调用顺序
http://blog.csdn.net/xw13106209/article/details/6899370 1.参考文献 参考1: C++继承中构造函数.析构函数调用顺序及虚函数的动态绑定 参考2 ...
- php 的 构造函数 和 析构函数
构造函数 在C++ java里的应用及其普遍,今天好好研究了一下 php 的 构造函数 和 析构函数 构造函数 和 析构函数 构造函数 void __construct ([ mixed $args ...
- C++-理解构造函数、析构函数执行顺序
先初始化序列中的函数调用,如果基类构造函数为非引用传递,则引起参数的拷贝构造 再: 先类内的成员构造函数(拷贝/默认),再类的构造函数:先基类,再派生类: 本文主要说明对象创建时构造函数的执行顺序,对 ...
- C++学习之类的构造函数、析构函数
在C++的类中,都会有一个或多个构造函数.一个析构函数.一个赋值运算操作符.即使我们自己定义的类中,没有显示定义它们,编译器也会声明一个默认构造函数.一个析构函数和一个赋值运算操作符.例如: //声明 ...
随机推荐
- 如何实现一个简易版的 Spring - 如何实现 @Component 注解
前言 前面两篇文章(如何实现一个简易版的 Spring - 如何实现 Setter 注入.如何实现一个简易版的 Spring - 如何实现 Constructor 注入)介绍的都是基于 XML 配置文 ...
- 推荐一个vuepress模板,一键快速搭建文档站
介绍 vuepress-template是一个简单的VuePress案例模板,目的是让用户可以直接clone这个仓库,作为初始化一个VuePress网站启动项目,然后在这个项目的基础上新增自定义配置和 ...
- HHVM的全称是"HipHop for PHP",开放源代码。采用PHP许可证授权!
http://hhvm.com/ https://github.com/xgqfrms/hhvm 什么是HHVM高性能服务器? HHVM是由Facebook公司出品的高性能开源服务器,用来执行hack ...
- Android Jetpack All In One
Android Jetpack All In One 在2018年,我们推出了Android Jetpack作为一组库,以帮助开发人员遵循最佳实践,减少样板代码以及编写可在Android版本和设备之间 ...
- Linux bash shell All In One
Linux bash shell All In One Linux https://tinylab.gitbooks.io/shellbook/content/zh/chapters/01-chapt ...
- css 命名冲突 & solution
css 命名冲突 & solution 类似这样,为了解决模块间可能存在的 css 命名冲突问题,需要单独提供给模块开发者一套模块开发环境:同时,文档上要有如何使用的规范说明. CSS 建议: ...
- ES6 Arrow Function return Object
ES6 Arrow Function return Object https://github.com/lydiahallie/javascript-questions/issues/220#issu ...
- HTML marquee
HTML marquee 跑马灯 https://developer.mozilla.org/en-US/docs/Web/HTML/Element/marquee https://developer ...
- uniapp 自定义弹窗组件
先上效果: 组件源码:slot-modal.vue <template> <view class="modal-container" v-if="sho ...
- Redis-第九章节-动态字符串
目录 概述 SDS(动态字符串) SDS(动态字符串)与c语言字符串的区别 1.概述 String类型底层实现的简单动态字符串sds,是可以修改的字符串.它采用预分配冗余空间的方式来减少内存的频繁分配 ...