问题描述:

class myClass {
public:
void SetNumber(int nNumber) {
m_nInt = nNumber;
}
private:
int m_nInt;
}; int main(int argc, char* argv[],int _version)
{
myClass Test;
Test.SetNumber(5);
return 0;
}

  上述代码中,SetNumber是如何识别得出来m_nInt是类的成员变量???

分析:

  main函数反汇编:

;省略进入main函数的部分汇编代码
push 5
lea ecx, [ebp+var_4] ;此处的[ebp+var_4]指的是Test对象的首地址
call j_myClass__SetNumber
;省略调用Set_Number之后的汇编代码

  从上述汇编代码可以看得出来,在main函数调用成员函数SetNumber之前,编译器先将实参5压栈,然后将Test对象的首地址保持到寄存器ecx中,最后直接调用成员SetNumber。从汇编代码中,还可以看出SetNumber的函数名是经过了修改的。

  SetNumber函数反汇编:

var_44= dword ptr -44h
var_4= dword ptr -4
arg_0= dword ptr 8 ;参数的地址 ;下面是进入函数后,将上一层的调用者的信息保持,压栈。
push ebp
mov ebp, esp
sub esp, 44h
push ebx
push esi
push edi
push ecx
lea edi, [ebp+var_44]
mov ecx, 11h
mov eax, 0CCCCCCCCh
rep stosd
pop ecx ;恢复ecx,this指针。
mov [ebp+var_4], ecx
mov eax, [ebp+var_4]
mov ecx, [ebp+arg_0]
mov [eax], ecx ;赋值,m_nInt=nNumber
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
retn 4  ;被调用者自己恢复栈
myClass__SetNumber endp

  从上述的反汇编代码可以看出,在底层成员函数和普通函数是没有区别的。我们所看到的类和对象的概念是编译器提供的,也就是说在调用成员函数的时候,编译器做了一些“小动作”:利用寄存器ecx来保持对象的首地址(即this指针),并以寄存器传参的方式传递给成员函数,这种调用被称为__thiscall。(注意:并不是所有的成员函数调用都是通过ecx来实现的,得看具体的编译器)

  __thiscall和__stdcall都是被调用者自己恢复栈。但是两者的区别在于,前者使用到一个寄存器来传递对象的首地址,而非通过栈传递的方式。

__thiscalll C++底层识别成员函数的更多相关文章

  1. C++反汇编第一讲,认识构造函数,析构函数,以及成员函数

    C++反汇编第一讲,认识构造函数,析构函数,以及成员函数 以前说过在C系列下的汇编,怎么认识函数.那么现在是C++了,隐含有构造和析构函数 一丶认识构造函数 高级代码: class MyTest { ...

  2. 成员函数指针与高性能C++委托

    1 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做“闭包(closure)”或“委托(delegate)”)在一些语言中已经证明了它宝贵的价值. ...

  3. [转]成员函数指针与高性能的C++委托

    原文(作者:Don Clugston):Member Function Pointers and the Fastest Possible C++ Delegates 译文(作者:周翔): 成员函数指 ...

  4. 理解ATL中的一些汇编代码(通过Thunk技术来调用类成员函数)

    我们知道ATL(活动模板库)是一套很小巧高效的COM开发库,它本身的核心文件其实没几个,COM相关的(主要是atlbase.h, atlcom.h),另外还有一个窗口相关的(atlwin.h), 所以 ...

  5. C++ 对象成员函数(非静态方法)

    1.神奇的inline语法与语义 inline语义C99和C++98都有.之前在单源文件编写的时候一直没有发现问题,但是一考虑到多文件的链接,就发现矛盾了. 一些inline的原则: 1. inlin ...

  6. C++类成员函数

    c++的两大特色是多态和模板.其中多态是通过继承和虚函数来实现的,其中虚函数是通过每个对象里面的虚表来实现的.如果这个对象的类有虚函数,那么这个类就有一张虚表,存的是每个虚函数的入口地址,而这个类的每 ...

  7. 成员函数指针与高效C++委托 (delegate)

    下载实例源代码 - 18.5 Kb 下载开发包库文件 - 18.6 Kb 概要 很遗憾, C++ 标准中没能提供面向对象的函数指针. 面向对象的函数指针也被称为闭包(closures) 或委托(del ...

  8. 【OOP】C++ const成员函数

    预备知识 1.代码转换分析技巧 在早期某些编译器会将C++代码翻译为C代码,然后使用C编译器生成可执行文件.其中翻译的一个转化就是:将this指针显式添加到成员函数的第一个参数位置上,并在成员函数调用 ...

  9. C++模板编程中只特化模板类的一个成员函数

    模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多数成员函数的功能可能是一模一样的,特化时我们可能只需要重新实现1.2个成员函数即可.在这种情况下,如果全 ...

随机推荐

  1. jupyter && ipython notebook简介

    2017-08-19 最近用了一下 ipython notebook 也就是 jupyter,这里有一个介绍还不错: http://www.cnblogs.com/howiewang/p/jupyte ...

  2. poj 3126 Bfs

    Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14539   Accepted: 8196 Descr ...

  3. MVC 控件系列

    下拉框:@Html.DropDownList("GroupId"); 文本框:@Html.TextBox("RoleCode", "", n ...

  4. 比较好的sql写法

    DECLARE @beginTime VARCHAR(20)= '2017-11-13 00:00:00';DECLARE @endTime VARCHAR(20)= '2017-11-13 23:0 ...

  5. 智课雅思词汇---二十一、名词性后缀acity是什么意思

    智课雅思词汇---二十一.名词性后缀acity是什么意思 一.总结 一句话总结:后缀:-acity [名词后缀] 构成抽象名词,表示性质.状态.情况.与形容词后缀-acious相对应 rapacity ...

  6. java:jsp: ResourceBundle国际化多语言

    java提供了一个资源类java.util.ResourceBundle来试下多国语言版本.其实ResourceBundle只是一个抽象的类,她有两个子类:ListResourceBundle,和,P ...

  7. python argpase模块简单使用

    python2.7 手册地址:https://docs.python.org/2/howto/argparse.html#id1 实现效果:脚本程序可以带参数 python arg.py -h 一.位 ...

  8. android:descendantFocusability用法简析(转)

        开发中很常见的一个问题,项目中的listview不仅仅是简单的文字,常常需要自己定义listview,自己的Adapter去继承BaseAdapter,在adapter中按照需求进行编写,问题 ...

  9. 使用visio 2010建立sql server数据模型——手动画、利用逆向工程

    基础数据库这个词不在新鲜,老早就提出了.咱们从出生,个人信息就被放到一个基本信息库中了,在全国各地,通过身份证号就能知道你的基本信息.最近米老师 下发了一个任务,让我们开发几个小项目,考试系统.选修课 ...

  10. 机器学习敲门砖:任何人都能看懂的TensorFlow介绍

    机器学习敲门砖:任何人都能看懂的TensorFlow介绍 http://www.jiqizhixin.com/article/1440