C++虚函数调用的反汇编解析

C++虚函数调用的反汇编解析

ID:37919049

大小:215.58 KB

页数:7页

时间:2019-06-02

C++虚函数调用的反汇编解析_第1页
C++虚函数调用的反汇编解析_第2页
C++虚函数调用的反汇编解析_第3页
C++虚函数调用的反汇编解析_第4页
C++虚函数调用的反汇编解析_第5页
资源描述:

《C++虚函数调用的反汇编解析》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、C++虚函数调用的反汇编解析虚函数的调用如何能实现其“虚”?作为C++多态的表现手段,估计很多人对其实现机制感兴趣。大约一般的教科书就说到这个C++强大机制的时候,就是教大家怎么用,何时用,而不会去探究一下这个虚函数的真正实现细节。(当然,因为不同的编译器厂家,可能对虚函数有自己的实现,呵呵,这就算是虚函数对于编译器的“多态”了:)。作为编译型语言,C++编译的最后结果就是一堆汇编指令了(这里不同于.NET的CLR)。今天,我就来揭开它的神秘面纱,从汇编的层面来看看虚函数到底怎么实现的。让大家对虚函数

2、的实现不仅知其然,更知其所以然。(本文程序环境为:PC+WindowsXPPro+VisualC++6.0,文中所得出来的结果和反映的编译器策略也只针对VC6.0的编译器)先看一段简单代码:CodeSegment:Line01:#includeLine02:Line03:classBase{Line04:public:Line05:void__stdcallOutput(){Line06:printf("ClassBase"n");Line07:}Line08:};Line09:Li

3、ne10:classDerive:publicBase{Line11:public:Line12:void__stdcallOutput(){Line13:printf("ClassDerive"n");Line14:}Line15:};Line16:Line17:voidTest(Base*p){Line18:p->Output();Line19:}Line20:Line21:int__cdeclmain(intargc,char*argv[]){Line22:Deriveobj;Line23:Te

4、st(&obj);Line24:return0;Line25:}程序的运行结果将是:ClassBase那么将Base类的Output函数声明(Line05)更改为:virtualvoid__stdcallOutput(){那么,很明显地,程序的运行结果将是:ClassDeriveTest函数这回算是认清楚了这个指针是一个指向Derive类对象的指针,并且正确的调用了其Output函数。编译器如何做到这一切的呢?我们来看看没有“virtual”关键字和有“virtual”关键字,其最终的汇编代码区别在那

5、里。(在讲解下面的汇编代码前,让我们对汇编来一个简单扫描。当然,如果你对汇编已经很熟练,那么goto到括号外面吧^_^。先说说上面的Output函数被声明为__stdcall的调用方式:它表示函数调用时,参数从右到左进行压栈,函数调用完后由被调用者恢复堆栈指针esp。其它的调用方式在文中描述。所谓的C++的this指针:也就是一个对象的初始地址。在函数执行时,它的参数以及函数内的变量将拥有如下所示的堆栈结构:(图1)如上图1所示,我们的参数和局部变量在汇编中都将以ebp加或者减多少来表示。你可能会有疑

6、问了:有时候我的参数或者局部变量可能是一个很大的结构体或者只是一个char,为什么这里ebp加减的都是4的倍数呢?恩,是这样的,对于32位机器来说,采用4个字节,也就是每次传输32位,能够取得最佳的总线效率。如果你的参数或者局部变量比4个字节大,就会被拆成每次传4个字节;如果比4个字节小,那还是每次传4个字节。再简单解释一下下面用到的汇编指令,这些指令都是见名知意的哦:①movdestination,source将source的值赋给destination。注意,下面经常用到了“[xxx]”这样的形式

7、,“xxx”对应某个寄存器加减某个数,“[xxx]”表示是取“xxx”的值对应的内存单元的内容。好比“xxx”是一把钥匙,去打开一个抽屉,然后将抽屉里的东西取出来给别人,或者是把别人给的东西放到这个抽屉里;②leadestination,[source]将source的值赋给destination。注意,这个指令就是把source给destination,而不会去把source对应的内存单元的内容赋给destination。好比是它就把钥匙给别人了;在调试时如果想查看反汇编的话,你应该点击图2下排最右

8、的按钮。(图2)其它指令我估计你从它的名字都能知道它是干什么的了,如果想知道其具体意思,这个应该参考汇编手册。:)一.没有virtual关键字时:(1)main函数的反汇编内容:Line22:Deriveobj;Line23:Test(&obj);//如果你把断点设置在22行,开始调试的时候VC会告诉你这是一个无效行,而把断//点自动移到下一行(Line23),这是因为代码中没有为Derive以及其基类定义构造函//数,而且编译器也没有为它生成一个默认的

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。