呵呵,类

来源:互联网 发布:网络兼职插画师 编辑:程序博客网 时间:2024/06/07 10:58

此篇幅主要研究简单类内存结构,用于学习反汇编

class CClassTest{public:CClassTest();~CClassTest();public:virtual void _stdcall SetAge(const int age);virtual int GetAge();void _stdcall Geive();void static StaticFun(int staticParam);private:void _stdcall SSk();private:int m_age;int m_session;static int m_global;};

int CClassTest::m_global = 12;CClassTest::CClassTest(){m_age = (int)GetTickCount();m_session = 10;}CClassTest::~CClassTest(){}int CClassTest::GetAge(){return m_age;}void CClassTest::SetAge(const int age){m_age += 56;m_session = 89;SSk();}void CClassTest::SSk(){m_age = 59;m_session += m_age;CClassTest::m_global += 98;}void _stdcall CClassTest::Geive(){m_session = m_age;}void CClassTest::StaticFun(int staticParam){printf("CClassTest::StaticFun param=%d\r\n", staticParam);}

//主程序调用部分

CClassTest *w = new CClassTest();int _tmain(int argc, _TCHAR* argv[]){//printf("w=%x size=%d\r\n", w, sizeof(*w));//普通函数int res = w->GetAge();printf("age=%d\r\n", res);//虚函数w->SetAge(argc);w->Geive();//静态函数CClassTest::StaticFun(156);return 0;}


这个类,我们定义的非常简单,主要用于研究其内存结构,代码没有任何意义,同时编译时关闭优化,不然这个类转为汇编后将面目全非。

1、类是怎么分布的

2、程序变量和函数怎么分布

3、静态成员怎么分布

4、调用类函数汇编是什么样的


首先看看MAIN函数:


可以看到头两行是例行保存SP,然后保存cx,

调用GetAge虚函数,图中1位置

开始正式工作,首先将[w]放入ax(w是一个指针,他的值就是一个地址,这里就是this指针),然后把[ax]的值(就是函数的虚表地址)放入dx,然后[dx+4]就是函数GetAge的地址(这个函数在类中是第二虚函数,vptr+0=SetAge, vptr+4=GetAge),我看的在调用GetAge之前,我们将this指针放入了cx中,便于在GetAge函数中使用,(注意,我发现只有在调用对象的第一个函数的时候才会这样传值,而在其后调用SetAge时,this指针式被当做参数push进去的,而且永远是第一个参数,也就是最后一个入栈的)

我们再看GetAge内容



函数定义的时候采用了GetAge(CClassTest *this)的方式,但是函数内部并没有使用到这个参数,而是重新定义了一个局部变量来存放this指针, 将cx入栈,这时候[bp-4]就是刚刚入栈的cx的位置,将cx的值放入其中,然后ax中存放的是对象的起始地址,偏移4字节,就是跳过虚函数指针变量(因为这个类带有虚函数),刚好是m_age变量的地址,[ax+4]放入ax函数调用结束



继续看=SetAge函数,就是图中2的部分,有两个push第一个是age参数,第二个是this指针,

SetAge函数体:



m_age是this偏移4字节,m_session是this偏移8字节,这样看代码应该很清楚了,然后是调用SSK()函数,可以看到,直接this指针入栈,然后调用,等价于 SSk(CClassTest* this);



下面看普通函数Geive调用(不占用类内存),图中3

首先是push了this指针,然后直接调用了一个函数,等价于调用了 Geive(CClassTest* this);


图说明了一切。



下面是类静态函数调用(不占用类内存),图中4位置


调用之前将staticParam入栈了



0 0
原创粉丝点击