一个简单函数的反汇编

来源:互联网 发布:奥凯软件怎么使用 编辑:程序博客网 时间:2024/05/19 01:10

void myfunction(int a,int b)

{

          int c=a+b;

}


(1)保存ebp。ebp总是被我们用来保存这个函数执行前的esp的值。执行完毕后,我们用ebp恢复esp;同时,调用此函数的上层函数也用ebp做同样的事情。所以先把ebp压入堆栈,返回之前弹出,避免ebp被我们改动。

push ebp

(2)保存esp到ebp中。

;保存ebp并把esp放入ebp中,此时ebp与esp同,都是这次函数调用时的栈顶

mov ebp,esp

(3)在堆栈中腾出区域来保存局部变量。

方法是:把esp减少一个数值,这就等于压入了一堆变量。要恢复时,只要把esp恢复成ebp中保存的数据就可以了。

保存ebx,esi,edi到堆栈中。函数调用后恢复。

sub esp,0cch

push ebx

push esi

push edi

(4)把局部变量初始化成全0cccccccch。0cch实际是int 3指令的机器码,是一个断点中断指令。因为局部变量不可能被执行,如果执行了,必然程序有错

,这时发生中断来提示开发者。这是VC编译Debug版本的特有操作。

lea edi,[ebp-0cch]            ;本来是要mov edi,ebp-0cch,但是mov不支持ebp-0cch这样的参数。所以对ebp-0cch取内容,而

                                            ;lea把内容的地址也就是ebp-0cch加载到edi中。目的是把保存局部变量的区域(从ebp-0cch开始的区域)初始化成全部0cccccccch

mov ecx,33h

mov eax,0cccccccch

rep stos dword ptr [edi]   ;串写入

(5)然后做函数里应该做的事。参数的获取是ebp+12字节为第二个参数,ebp+8为第一个参数(注意倒序压入),依次增加。最后ebp+4字节处是要返回的地址。

(6)恢复ebx,esi,edi,esp,ebp,最后返回。代码如下:

pop edi                    ;恢复edi,esi,ebx

pop esi

pop ebx

mov esp,ebp    ;恢复原来的ebp和esp,让上一个调用的函数正常使用

pop ebp

ret

另外,该函数没有返回值。如果要返回值,函数应该在返回之前,把返回值放入eax中,外部通过eax获得返回值。