2、关于如何计算局部变量的大小问题

作者在 2008-07-18 22:44:59 发布以下内容
经常反汇编的话,在调用子程序开始的地方,都会看到:
push ebp
mov ebp,esp
add esp,FFFFFFF8  ;也可能是其它的值
... ...
这种情况的指令形式。
编译器采用的是“+”的方法来开辟局部变量的空间的。
其实,我们要知道FFFFFFF8真正的值的话,就得采用“补码取反加1”才知道它的“绝对值”,是8。
有没有更加方便的方法呢?有!
我们知道,正数+负数=0(前提是两者绝对值相等),所以,我们用“0-负数”的方法也可以得到“正数”,即“绝对值”。
00000000-FFFFFFF8=8
00000000-FFFFFFAC=54
当然,这种算法涉及到最后一位的借位问题,把这点忽略掉是不会影响我们得到“绝对值”的。
文章评论,共6条
missiyou
2008-07-20 14:48
1
我用计算器,0-FFFFFFAC=54&nbsp;&nbsp;&nbsp;哦!!<br />
说的好!<br />
不要误人子弟啊,
ONEPROBLEM(作者)
2008-07-20 23:00
2
呵呵~~确实误人子弟啊.<br />
00000000-FFFFFFAC=64,是错误的.其实在第二个0已经被借了一位,所以在第二位0减A时,应该是5.结果是54.<br />
谢谢missyou<br />
正文中已更正.<br />
补充:当然,missyou也说得对,用计算器就可以了.哈哈~~~~误人子弟.
你们都要疼我哦
2008-07-21 23:23
3
这个...这个...我记得好象是进入子程序,开辟栈空间,是用减的,比如减8 减12...&nbsp;&nbsp;用完以后恢复,用加的. 因为本身栈空间是由高到低的方向生长.<br />
所以我们只要知道栈空间的开辟是要减的就可以. <br />
至于表现形式,这和编译器或者反汇编的引擎有关,有的是SUB 正, 有的是ADD 负 ,&nbsp;&nbsp;还有的是开辟用ADD 负,恢复用ADD 正.<br />
FFFFFFF8在32位机里本身就是负数.<br />
另外开辟出的是子程序使用的栈空间, 不一定绝对是局部变量的大小.<br />
ONEPROBLEM 学的真细.
你们都要疼我哦
2008-07-21 23:38
4
另外... FFFFFFAC...&nbsp;&nbsp;&nbsp; 32位机4字节对齐,都是4的倍数,54......晕.
ONEPROBLEM(作者)
2008-07-21 23:53
5
楼上说的是。<br />
这个FFFFFFAC是我随手乱写的。谢谢指教。
missiyou
2008-07-22 13:54
6
【例】按__stdcall约定调用函数test2(Par1, Par2) <br />
 <br />
 <br />
push par2 ; 参数2<br />
push par1 ; 参数1<br />
call test2;<br />
{<br />
push ebp ; 保护现场原先的EBP指针<br />
mov ebp, esp ; 设置新的EBP指针,指向栈顶<br />
mov eax, [ebp+0C] ; 调用参数2<br />
mov ebx, [ebp+08] ; 调用参数1<br />
sub esp, 8 ; 若函数要用局部变量,则要在堆栈中留出点空间<br />
…<br />
add esp, 8 ; 释放局部变量占用的堆栈<br />
pop ebp ; 恢复现场的ebp指针<br />
ret 8 ; 返回(相当于ret; add esp,8)<br />
}<br />
应该来好好的完善一下。
游客请输入验证码