src(debug vesion by vs2008 sp1 on xp sp3)
#include<iostream>
using namespace std;
class SimpleClass{
public:
int x;
void HelloWorld(){
printf("hello,mao");
}
};
int main(int argc,char **argv)
{
SimpleClass myclass;
myclass.HelloWorld();
return 0;
}
反匯編后的結構
--- c:vc6myprojectsvsclasstestvsclasstestingome.cpp ----------------------
1: #include<iostream>
2: using namespace std;
3:
4: class SimpleClass{
5: public:
6: int x;
7: void HelloWorld(){
00411440 push ebp
00411441 mov ebp,esp
00411443 sub esp,0CCh
00411449 push ebx
0041144A push esi
0041144B push edi
0041144C push ecx
0041144D lea edi,[ebp-0CCh]
00411453 mov ecx,33h
00411458 mov eax,0CCCCCCCCh
0041145D rep stos dword ptr es:[edi] //將局部變量空間全部初始化為0xcc (0x33*4=CC)
(store to string addr edi by dword,repeat time is ecx,filled-word is eax.)
0041145F pop ecx
00411460 mov dword ptr [ebp⑻],ecx //ebp⑻處是個變量,寄存當前類實例的地址,那末,我們的x去了哪里呢。
---類中的變量不是函數中的局部變量,方法棧空間大小和類成員數目沒有關系。
8: printf("hello,mao");
00411463 mov esi,esp
00411465 push offset string "hello,mao" (415800h)
0041146A call dword ptr [__imp__printf (4182BCh)] //從導入表中取得地址,導入表iat在4182BCh處
00411470 add esp,4
00411473 cmp esi,esp
00411475 call @ILT+310(__RTC_CheckEsp) (41113Bh)
9: }
0041147A pop edi
0041147B pop esi
0041147C pop ebx
0041147D add esp,0CCh
00411483 cmp ebp,esp
00411485 call @ILT+310(__RTC_CheckEsp) (41113Bh)
0041148A mov esp,ebp
0041148C pop ebp
0041148D ret
main函數部份
17: SimpleClass myclass;
18: myclass.HelloWorld();
004113CE lea ecx,[myclass]
004113D1 callSimpleClass::HelloWorld (41114Ah)
19: return 0;
004113D6 xor eax,eax
從圖中可以看出來,履行類中方法的時候,會先取出實例化類的地址(ecx= myclass
),也就是說編譯器讓類的內部方法實現的時候已引入了隱藏變量實例化的類指針
。
類中的變量不是類方法中的變量,類方法訪問類中變量是通過ecx作為隱藏參數傳入的,所以類方法中沒有分配空間寄存類成員。