C 对象布局及多态实现之成员函数的调用
2008-02-23 05:27:08来源:互联网 阅读 ()
下面我们看看引入虚继承后的影响。为了有所对比我们首先看看普通成员函数的调用情况。
执行如下代码,他包括了对象的普通成员函数调用,类的静态成员函数调用、通过指针调用普通成员函数:
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指针来找到对象地址的。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇: C 箴言:谨慎使用私有继承
下一篇: C 对象布局及多态实现探索之虚函数调用
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash