程序员人生 网站导航

从汇编学习c++ 之 类的方法调用

栏目:php教程时间:2015-06-11 08:52:46

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作为隐藏参数传入的,所以类方法中没有分配空间寄存类成员。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐