﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-我的一片天-文章分类-WIN32汇编</title><link>http://www.cnitblog.com/xkz/category/6648.html</link><description>我的一片天</description><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 14:56:17 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 14:56:17 GMT</pubDate><ttl>60</ttl><item><title>反汇编下找C++的类及成员函数</title><link>http://www.cnitblog.com/xkz/articles/37507.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sat, 08 Dec 2007 14:11:00 GMT</pubDate><guid>http://www.cnitblog.com/xkz/articles/37507.html</guid><wfw:comment>http://www.cnitblog.com/xkz/comments/37507.html</wfw:comment><comments>http://www.cnitblog.com/xkz/articles/37507.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/xkz/comments/commentRss/37507.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/xkz/services/trackbacks/37507.html</trackback:ping><description><![CDATA[<p>C++中类的使用</p>
<p><span style="FONT-FAMILY: Arial">C010 obj; <br>PRINT_OBJ_ADR(obj) <br>obj.foo();</span> <br>执行结果：obj's address is : 0012F843</p>
<p>首先我们看看对象的普通成员函数调用，obj.foo();，对应的汇编代码为：</p>
<p>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Arial; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">00422E09&nbsp;lea&nbsp;ecx,[ebp</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">FFFFF967h]&nbsp;<br></span><span style="COLOR: #000000">00422E0F</span><span style="COLOR: #000000">&nbsp;call&nbsp;0041E289&nbsp;</span></div>
<p>第1行把对象的地址存入ecx寄存器，执行完这行指令后，我们要以看到ecx中的值为0x0012F843，就是前面打印出的值。如果函数需要传递参数，我们还会在前面看到一些push指令。在第2行我们可以看到call的是一个直接的地址，这也就是静态绑定。即函数的调用地址在编译时已经被编译器决议。 </p>
<p>跟踪进去我们要以看到是一条跳转指令，继续执行可以看到真正的函数代码部分，如下：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; COLOR: blue; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; FONT-FAMILY: Arial; BACKGROUND-COLOR: #eeeeee">01&nbsp;00425FE0&nbsp;push&nbsp;ebp&nbsp;<br>02&nbsp;00425FE1&nbsp;mov&nbsp;ebp,esp&nbsp;<br>03&nbsp;00425FE3&nbsp;sub&nbsp;esp,0CCh&nbsp;<br>04&nbsp;00425FE9&nbsp;push&nbsp;ebx&nbsp;<br>05&nbsp;00425FEA&nbsp;push&nbsp;esi&nbsp;<br>06&nbsp;00425FEB&nbsp;push&nbsp;edi&nbsp;<br><span style="BACKGROUND-COLOR: red">07&nbsp;00425FEC&nbsp;push&nbsp;ecx&nbsp;<br></span>08&nbsp;00425FED&nbsp;lea&nbsp;edi,[ebp+FFFFFF34h]&nbsp;<br>09&nbsp;00425FF3&nbsp;mov&nbsp;ecx,33h&nbsp;<br>10&nbsp;00425FF8&nbsp;mov&nbsp;eax,0CCCCCCCCh&nbsp;<br>11&nbsp;00425FFD&nbsp;rep&nbsp;stos&nbsp;dword&nbsp;ptr&nbsp;[edi]&nbsp;<br>12&nbsp;00425FFF&nbsp;pop&nbsp;ecx&nbsp;<br><span style="COLOR: red">13&nbsp;00426000&nbsp;mov&nbsp;dword&nbsp;ptr&nbsp;[ebp-8],ecx&nbsp;<br></span>14&nbsp;00426003&nbsp;mov&nbsp;eax,dword&nbsp;ptr&nbsp;[ebp-8]&nbsp;<br>15&nbsp;00426006&nbsp;mov&nbsp;byte&nbsp;ptr&nbsp;[eax],2&nbsp;<br>16&nbsp;00426009&nbsp;pop&nbsp;edi&nbsp;<br>17&nbsp;0042600A&nbsp;pop&nbsp;esi&nbsp;<br>18&nbsp;0042600B&nbsp;pop&nbsp;ebx&nbsp;<br>19&nbsp;0042600C&nbsp;mov&nbsp;esp,ebp&nbsp;<br>20&nbsp;0042600E&nbsp;pop&nbsp;ebp&nbsp;<br>21&nbsp;0042600F&nbsp;ret</div>
<p>&nbsp;<br>我们看看第7行，把ecx寄存器入栈，后面4行初始化了函数的堆栈中的保存局部变量的部分。第12行弹出ecx值，到这里时ecx的值保持为在函数调用前存入的对象内存地址，第13行就是保存this指针的值，作为一个局部变量。这样我们就知道了VC7.1不是象传递普通函数那样通过压栈来传递this 指针，而是通过ecx寄存器来传递。第14、15行利用这个this指针给对象的成员变量进行了赋值。<br><br><br></p>
<img src ="http://www.cnitblog.com/xkz/aggbug/37507.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/xkz/" target="_blank">xyz</a> 2007-12-08 22:11 <a href="http://www.cnitblog.com/xkz/articles/37507.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>类似Lea EAX,[EBX+10]的作用</title><link>http://www.cnitblog.com/xkz/articles/37506.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sat, 08 Dec 2007 13:37:00 GMT</pubDate><guid>http://www.cnitblog.com/xkz/articles/37506.html</guid><wfw:comment>http://www.cnitblog.com/xkz/comments/37506.html</wfw:comment><comments>http://www.cnitblog.com/xkz/articles/37506.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/xkz/comments/commentRss/37506.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/xkz/services/trackbacks/37506.html</trackback:ping><description><![CDATA[<p>Lea是返回偏移地址，对于 Lea EAX,s1 这样很好解释,就是返回变量s1的偏移地址</p>
<p>Lea EAX,[EBX+10]就比较复杂了</p>
<p>[EBX+10]表示EBX+10后作为地址,此地址指向位置的值,取的是EBX+10地址内的内容。</p>
<p>那Lea究竟是把这个内容作为地址存入EAX，还是把这个内容的地址赋给EAX呢？如果是后者，那不是跟MOV EAX,EBX+10的效果一样了？</p>
<p>&nbsp;</p>
<p>实际的效果应该是后者，Mov EAX,EBX+10是非法的语句，汇编不允许操作数有2个寄存器和立即数存在。</p>
<p>&nbsp;</p>
<p>Lea EAX,[EBX+10]的作用就是把EBX+10作为地址存入EAX。</p>
<img src ="http://www.cnitblog.com/xkz/aggbug/37506.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/xkz/" target="_blank">xyz</a> 2007-12-08 21:37 <a href="http://www.cnitblog.com/xkz/articles/37506.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>堆栈ESP载调用函数时的变化。</title><link>http://www.cnitblog.com/xkz/articles/37505.html</link><dc:creator>xyz</dc:creator><author>xyz</author><pubDate>Sat, 08 Dec 2007 13:23:00 GMT</pubDate><guid>http://www.cnitblog.com/xkz/articles/37505.html</guid><wfw:comment>http://www.cnitblog.com/xkz/comments/37505.html</wfw:comment><comments>http://www.cnitblog.com/xkz/articles/37505.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/xkz/comments/commentRss/37505.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/xkz/services/trackbacks/37505.html</trackback:ping><description><![CDATA[<p>堆栈指针ESP的变化方法：先ESP=ESP-4，然后把要PUSH的值放入[ESP]里,就是说ESP是先变化到新的地址位置，然后在存入值，接着就停留在那里等待新的PUSH。</p>
<p>&nbsp;</p>
<p>WIN32程序在调用函数时的压栈顺序如下：</p>
<p>ESP-4&nbsp; &nbsp;|___EBP ___|&nbsp;&nbsp; 进入函数的ESP值,一般会执行PUSH EBP&nbsp;&nbsp; MOV EBP,ESP，则EBP就是入函数的堆栈指针，以便通过EBP引用函数内的变量</p>
<p>ESP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;|___EIP____|&nbsp;&nbsp; 调用函数后，自动压入下一条指令的EIP</p>
<p>&nbsp;</p>
<p>以STDCALL方式的函数，参数由右到左分别压入，在处理完后必须恢复ESP的值到指向EIP的栈地址。一般函数可通过retun 4 这样的方式把ESP+4。</p>
<img src ="http://www.cnitblog.com/xkz/aggbug/37505.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/xkz/" target="_blank">xyz</a> 2007-12-08 21:23 <a href="http://www.cnitblog.com/xkz/articles/37505.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>