C++的优化汇编代码.doc

  1. 1、本文档共5页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
C的优化汇编代码

C++的优化汇编代码 对于一个资深程序员来说,了解我们的程序的最底层的运行机制是很重要的,特别对于C/C++程序员来说,这点显得尤为突出。 在很多情况下,知道其底层运行机制对我们理解更深层次的东西是非常有帮助的。比如说,如果你对这些底层的运行记住比较熟悉,那么可能在COM编程中,你会更容易理解他的虚表(vtbl)技术,或者windows编程中经常涉及的TRUNK机制。 其实在不同的C/C++编译器中,由同样的C/C++代码编译成的汇编(机器)代码是不同的。主要讨论Microsoft Visual C++.Net编译器生成的机器代码。Visual C++不同版本的编译器生成的代码没有什么大的区别,这些在讨论后面的实现中会有详细的论述。 C++代码与汇编码 下面我要给出一个全局函数代码,为了简单起见,代码比较简单。 Void InitFun(Function* pFun) { pFun-SetAge(34); PFun-SetName(brucewang); } Function是我们定义的一个类,这个函数的功能是接受一个Function类型对象的指针以对该对象进行初始化。SetAge和SetName是Function中定义的两个函数,分别设置Function中定义的age和name属性。下面给出Visual C++编译之后的汇编代码: ;前期工作:设置基址指针,为局部变量分配内存 push ebp Mov ebp,esp Sub esp,0C0h ;保存三个常用辅助寄存器原始信息 Push ebx Push esi Push edi ;以0CCCCCCCCh值初始化局部变量内存空间 Lea edi,[ebp-0C0h] Mov ecx,30h Rep stos dword ptr [edi] ;函数主体,执行函数逻辑 Push 22h Mov ecx,dword prt [pFun] Call Function::SetAge Push offset string brucewang Mov ecx,dword ptr[pFun] Call Function::SetName Pop edi Pop esi Pop ebx Add esp 0C0h Cmp ebp,esp Call @ILT+3240(_RTC_CheckEsp) Mov esp,ebp Pop ebp 解析C++Debug版本汇编代码 首先,我们进入函数体,就要执行三条初始化指令: push ebp Mov ebp,esp Sub esp,0C0h 我们知道,ebp寄存器在Visual C++中是被默认用来做基址指针的。因此,在刚进入函数执行阶段,都要对ebp进行相应的操作。 第一步,先保存当前ebp中的值,然后将他用在本函数中。 第二步,获取当前堆栈指针,获得的堆栈指针将作为局部变量的基址指针使用。最要引起我们注意的是第三条语句,在C++中,程序局部变量是在堆栈中分配的,可是并没有在每个函数中发现诸如AllocMem等申请内存的函数或指令。实际上,函数中的局部变量空间的分配就是由这条指令完成的。在本例中,程序分配了0C0h字节的空间供该子函数使用。至于为什么要分配多少字节,我们在后面再讨论。 其次,是辅助寄存器ebx,edi,esi的状态保存。作为通用寄存器,他们经常被用在一些常见的操作中,特别是在字符串、数组等的操作中,edi、esi通常作为存储目的、源数据的地址指针来使用。因此这里先保存这三个寄存器的值。虽然在本例中,并没有用到ebx和esi,但是还是按照惯例保存了。 第四步,就是函数调用了。早前面给出的C++源代码中,我们有两个调用类成员函数的语句: pFun-SetAge(34); PFun-SetName(brucewang); 在谈到对象的方法的调用上,我们有必要讨论它的具体存储方式,在C++中,对象的成员数据和方法是分开存储的。这样,对同一个类的多个对象,可以共享相同的代码。 这就为我们引入了一个新的问题:当我们调用某个方法是,类方法代码如何知道应该对那个对象数据进行操作呢?在C++代码级别,这个问题是不存在的,因为C++调用对象方法时是加上对象限定符的。但是在汇编码级别是怎样处理的呢?在Visual C++中,对象数据指针是用ecx寄存器来传递的,也就是说在方法中对对象数据的访问,是使用ecx寄存器中的数值来作为对象基址指针对对象数据进行存取等操作的。实际上,这个ecx就是你在实现类成员方法是在其中使用的this指针。所以你看到的汇编代码是这样的: Push 22h Mov ecx,dword prt [pFun] Call Function::SetAge 第五步,退出函数是的恢复工作,受限是恢复前面提到的3个常用的辅助寄存器:ebx、ed

文档评论(0)

kakaxi + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档