当前位置:天才代写 > tutorial > C语言/C++ 教程 > C++工具机关及多态实现之成员函数的挪用

C++工具机关及多态实现之成员函数的挪用

2017-11-06 08:00 星期一 所属: C语言/C++ 教程 浏览:697

从这部门开始我们除了操作内存的信息打印来举办摸索外,更多的会通过跟踪和调查编译器发生的汇编代码来领略编译器对这些语言特性的实现方法。汇编方面常识的接头超出了本文的范畴,我只对和我们接头相关的汇编代码举办理会。领略本文要接头的常识并不需要有很完整的汇编常识,但必需相识起码的观念。

下面我们看看引入虚担任后的影响。为了有所比拟我们首先看看普通成员函数的挪用环境。

执行如下代码,它包罗了工具的普通成员函数挪用,类的静态成员函数挪用、通过指针挪用普通成员函数:

C010 obj;
PRINT_OBJ_ADR(obj)
obj.foo();
C012::sfoo();
C010 * pt = &obj;
pt->foo();

功效如下:

obj’s address is : 0012F843

这是obj工具的内存地点。

首先我们看看工具的普通成员函数挪用,obj.foo();,对应的汇编代码为:

00422E09 lea ecx,[ebp+FFFFF967h]

00422E0F call 0041E289

第1行把工具的地点存入ecx寄存器,执行完这行指令后,我们要以看到ecx中的值为0x0012F843,就是前面打印出的值。假如函数需要通报参数,我们还会在前面看到一些push指令。在第2行我们可以看到call的是一个直接的地点,这也就是静态绑定。即函数的挪用地点在编译时已经被编译器决策。

跟踪进去我们要以看到是一条跳转指令,继承执行可以看到真正的函数代码部门,如下(注:为了接头利便我在第行前面加了一个行号):

01 00425FE0 push ebp
02 00425FE1 mov ebp,esp
03 00425FE3 sub esp,0CCh
04 00425FE9 push ebx
05 00425FEA push esi
06 00425FEB push edi
07 00425FEC push ecx
08 00425FED lea edi,[ebp+FFFFFF34h]09 00425FF3 mov ecx,33h
10 00425FF8 mov eax,0CCCCCCCCh
11 00425FFD rep stos dword ptr [edi]12 00425FFF pop ecx
13 00426000 mov dword ptr [ebp-8],ecx
14 00426003 mov eax,dword ptr [ebp-8]15 00426006 mov byte ptr [eax],2
16 00426009 pop edi
17 0042600A pop esi
18 0042600B pop ebx
19 0042600C mov esp,ebp
20 0042600E pop ebp
21 0042600F ret

我们看看第7行,把ecx寄存器入栈,后头4行初始化了函数的仓库中的生存局部变量的部门。第12行弹出ecx值,到这里时ecx的值保持为在函数挪用前存入的工具内存地点,第13行就是生存this指针的值,作为一个局部变量。这样我们就知道了VC7.1不是象通报普通函数那样通过压栈来通报this 指针,而是通过ecx寄存器来通报。第14、15行操作这个this指针给工具的成员变量举办了赋值。

再看看静态成员函数挪用的汇编代码:

00422E14 call 0041DD84

很是直接,因为它不需要处理惩罚this指针,跟踪到函数的汇编代码,可以看到同样不需要处理惩罚this指针。详细的代码这里就不列出来了。

再看看通过指针挪用普通成员函数pt->foo();,发生的汇编代码如下:

00422E25 mov ecx,dword ptr [ebp+FFFFF958h]

00422E2B call 0041E289

和通过工具挪用普通成员函数的代码差不多。不外存工具地点到ecx寄存器地,是通过解引用pt指针来找到工具地点的。

 

    关键字:

天才代写-代写联系方式