C语言最简main函数的反汇编代码解析.docxVIP

C语言最简main函数的反汇编代码解析.docx

  1. 1、本文档共3页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
目前我们写的最简单的Main函数如下: 代码: #include?stdafx.h int?_tmain(int?argc,?_TCHAR*?argv[]) { ??return?0; } 利用VS编译器将运行时程序反汇编,结果如下: 代码: int?_tmain(int?argc,?_TCHAR*?argv[]) { 010C13A0??push????????ebp?? 010C13A1??mov?????????ebp,esp?? 010C13A3??sub?????????esp,0C0h?? 010C13A9??push????????ebx?? 010C13AA??push????????esi?? 010C13AB??push????????edi?? 010C13AC??lea?????????edi,[ebp-0C0h]?? 010C13B2??mov?????????ecx,30h?? 010C13B7??mov?????????eax,0CCCCCCCCh?? 010C13BC??rep?stos????dword?ptr?es:[edi]?? ??return?0; 010C13BE??xor?????????eax,eax?? } 010C13C0??pop?????????edi?? 010C13C1??pop?????????esi?? 010C13C2??pop?????????ebx?? 010C13C3??mov?????????esp,ebp?? 010C13C5??pop?????????ebp?? 010C13C6??ret 看起来汇编很头疼吧,那么让我们来茅塞顿开吧。首先了解一下以前几个未知半懂的汇编指令的含义: 代码: push????????ebp mov?????????ebp,esp push:把一个32位操作数压入栈中,这个操作导致esp被减4。?ebp被用来保存这个函数执行前的esp的值,执行完毕后用ebp恢复esp。同时,调用此函数的上层函数也用ebp做同样的事情。所以先把ebp压入堆栈,返回之前弹出,避免ebp被我们改动。 代码: xor?????????eax,eax ret xor?eax,eax常用来代替mov?eax,0。清零操作。在windows中,函数返回值都是放在eax中然后返回,外部从eax中得到返回值。这就代表return?0操作。 代码: lea?????????edi,[ebp-0C0h] lea取得第二个参数代表的地址放入第一个参数代表的寄存器中。 代码: mov?????????ecx,30h?? mov?????????eax,0CCCCCCCCh?? rep?stos????dword?ptr?es:[edi]?? stos是串存储指令,它的功能是将eax中的数据放入edi所指的地址中,同时edi会增加4个字节。Rep使指令重复执行ecx中填写的次数。 由于CPU的寄存器有限,而且操作寄存器会影响标志值,push作用是压栈,pop是退栈。即保存寄存器标志的值和寄存器本身的值,以便在函数调用完毕后恢复原有的标志值。这也是为什么我们见到在调用某个函数或者运行一个程序时,入口总是push一堆寄存器的东东,也就是这个原因。 通过上面的基础知识,我们来看看main函数的反汇编解释: 代码: int?_tmain(int?argc,?_TCHAR*?argv[]) { 010C13A0??push????????ebp?? ;保存ebp,返回之前弹出,避免ebp被我们改动。push操作使esp减小,esp不变 010C13A1??mov?????????ebp,esp ;?ebp被用来保存这个函数执行前的esp的值,执行完毕后用ebp恢复esp ;原ebp值已经被压栈(位于栈顶),而新的ebp又恰恰指向栈顶 ;此时ebp寄存器就已经处于一个非常重要的地位,该寄存器中存储着栈中的一个地址(原ebp入栈后的栈顶) ;从该地址为基准,向上(栈底方向)能获取返回地址、参数值(假如main中有参数,“获取参数值”会比较容易理解 ;向下(栈顶方向)能获取函数局部变量值,而该地址处又存储着上一层函数调用时的ebp值 010C13A3??sub?????????esp,0C0h? ;把esp往上移动一个范围,等于在栈中开辟一片空间存储main函数的局部变量 ;由于冯诺依曼机是小端模式,所以sub操作可以理解为将esp栈顶减去,实际上是为栈增加空间 010C13A9??push????????ebx?? 010C13AA??push????????esi?? 010C13AB??push????????edi?? ;保存三个寄存器的值,待main结束恢复,原来的值被

文档评论(0)

ktj823 + 关注
实名认证
文档贡献者

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

1亿VIP精品文档

相关文档