(3)函数体代码
大家可以看以00401E3D一直到最后的代码就是在构造函数里面对全局变量g_Number加一并输出的过程,最后构造函数将对象的起始地址放入EAX寄存器中并返回。
3.1.2形字类中没有虚函数
当申请一个类对象时,如果这个类中没有虚函数情况则会发现一些变化。还是基于上面的CMemoryItem类,但是修改一下它的析构函数详细如下:
virtual ~CMemoryItem()这个原来类中析构函数的声明现在把virtual关键字去掉再来跟踪一下程序的执行情况,下面列出关键部分汇编代码:
00402739 add eax,0Ah
0040273C push eax
0040273D push offset THIS_FILE (00416690)
00402742 push 4
00402744 call operator new (00402310)
00402749 add esp,0Ch
上面是程序编译后申请内存部分的汇编代码,前三句与上面第一节中的汇编代码没有什么不同,但注意一下第四句,这句是告诉new函数需要为对象申请内存的长度,再回顾一下上面汇编代码,它压栈的是8,但为什么这里是4呢? 保留这个问题再向下跟踪代码来寻找答案。看看下面这部分代码:
0040275C mov ecx,dword ptr [ebp-1Ch]
0040275F call @ILT+15(CMemoryItem::CMemoryItem) (00401014)
00402764 mov dword ptr [ebp-28h],eax
显然这部分代码与上节的代码是没有区别的,仔细看下面的代码:
00401E30 push ebp
00401E31 mov ebp,esp
00401E33 push 0FFh
00401E35 push offset __ehhandler$??0CMemoryItem@@QAE@XZ (00403959)
00401E3A mov eax,fs:[00000000]
00401E40 push eax
00401E41 mov dword ptr fs:[0],esp
00401E48 sub esp,44h
00401E4B push ebx
00401E4C push esi
00401E4D push edi
00401E4E push ecx
00401E4F lea edi,[ebp-50h]
00401E52 mov ecx,11h
00401E57 mov eax,0CCCCCCCCh
00401E5C rep stos dword ptr [edi]
00401E5E pop ecx
00401E5F mov dword ptr [ebp-10h],ecx
00401E62 mov ecx,dword ptr [ebp-10h]
00401E65 call CString::CString (004022b6)
00401E6A mov dword ptr [ebp-4],0
00401E71 mov eax,[g_Number (00416900)]
00401E76 add eax,1
|