您的位置:首页 > 编程语言 > C语言/C++

C++函数调用之thiscall

2015-09-09 20:20 627 查看
C++函数调用之thiscall

所有c++对象共享类中的一份代码拷贝,那c++是怎么实现对每个对象的数据的正确操作?

这就要归功与c++的thiscall, C++会为每个类成员函数传递一个this指针即指向被操作对象的地址做为成员函数的隐含参数(被static修饰的除外 ),VC下编译器在调用非static函数时会把这个指针放入ecx寄存器,,,,,,

 

下面让我们来看看thiscall在c++中到底是怎么实现的,,,

有如下代码

 


查看反汇编代码

 


发现在调用构造函数与fadd函数之前有lea ecx,[ebp-4]指令

那么这条指令有什么用?

[ebp-4]这个内存单元存放的是什么?

首先让我们来解答第二个问题

从反汇编代码中我们可以看到在第17行以后的三条指令是实例化一个对象

所以[ebp-4]这个单元的地址就是编译器为对象a分配的栈空间的首地址(单单的[ebp-4]没有什么意义,仅仅取得它的地址也没什么意义,在于怎么使用它,,,);

而lea ecx,[ebp-4]表示把对象a的地址放入ecx寄存器

好下面来让我们解决第一个问题

从第一个问题的解答我们知道ecx存放的是对象的地址,所以ecx中的值就是c++中所谓的this指针,所以lea ecx,[ebp-4]就是为成员函数传递this指针的,现在这个指针是没有什么意义,它代表指向从此地址起的所有空间

下面让我们进入fadd函数内部查看其反汇编代码



我们来跟踪下ecx寄存器的使用情况

Push ecx 把ecx(this)的值压栈

mov ecx,11h 把ecx当作计数器使用

pop ecx 把值(this)从栈中弹到exc中

mov dword ptr [ebp-4],ecx 把ecx值(this)放到成员函数的栈中

到此ecx的任务已经完成了

下面让我们看下成员函数到底是怎样去引用一个对象的成员变量的

首先把[ebp-4] (this) 放入eax

然后mov ecx,dword ptr [eax] 指令(dword的修饰让对此地址的使用变的有意义)到this指针(eax寄存器的值)指向的地址取四个字节即成员变量a(编译器只为对象分配存放成员变量与虚表指针的空间),放到ecx寄存器中,然后add ecx,1 (a+1)

最后mov edx,dword ptr [ebp-4]把this指针放到edx中,mov dword ptr [edx],ecx 把ecx的值(a+1)放到this指针(edx的值)指向的内存中(即成员变量a中)

到此成员函数已经正确引用到了成员变量

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息