汇编_CALL的执行流程浅析

今天我们说一说,CALL就是调用函数,CALL的流程是怎么样的,它是怎么执行的,从哪里来?又将回哪里去?

我用易语言,写了一个函数,反汇编后很简单的一段代码

00400050 call 00490050

00400055 mov ecx,eax

00490050 PUSH EBP

00490051 MOV EBP,ESP

00490053 MOV EAX,00000001

00490058 MOV ESP,EBP

0049005A POP EBP

0049005B RET

00490050 到0049005B 这一段就是一个函数,非常简单,什么都没做,直接返回一个常数1

计算机是怎么执行的呢?

首先 从00400050开始,call 00490050这一句

call 00490050

等于

push 00400055

jmp 00490050

假如执行CALL 00490050这一句之前 ESP=00120000

我们假设00120000这时候的内存是这样的

0011FFEA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00120000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

我们现在其实下面就是要执行 push 00400055

                                      jmp  00490050

执行push 00400055这行汇编指令 其实是CPU经过了2个步骤 ,1,sub esp,4

2,mov [esp],00400055

 我们来看下ESP位置 esp=0011FFFC

0011FFEA 00 00 00 00 00 00 00 00 00 00 00 00 55 00 40 00

00120000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

 然后执行下一条指令,jmp 00490050 这一条esp没变化,跳到00490050处来执行

00490050 PUSH EBP

**首先00490050处又是一个push,执行完毕后

esp=11FFF8

0011FFEA 00 00 00 00 00 00 00 00 ebp放在这里  55 00 40 00

00120000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

现在注意看一下 [esp]里现在存放是进CALL之前ebp ,而[esp+4]存放的就是CALL指令后面的地址

**下面执行00490051 mov ebp,esp

这个时候 ebp=esp=11FFF8,那么我们知道 [ebp]=进CALL前的ebp [ebp+4]=返回地址,如果是复杂点带参数的函数,你会发现

[ebp+8]是参数一,[ebp+c]是参数二等等

**下面执行mov eax,00000001.这句没什么好解释的,一般返回值放在eax中,这个就是把返回值赋值为1

**下面执行mov esp,ebp

这个时候esp=ebp=11FFF8

**下面执行pop ebp ,这句等价于 mov ebp,[esp]

                                            add esp,4

执行完毕后

我们来看[esp]里存放是进CALL前的ebp,那么现在ebp=进CALL前的ebp

然后现在 esp加了个4后 又等于了0011FFFC  我们来看看

0011FFEA 00 00 00 00 00 00 00 00 ebp放在这里  55 00 40 00

00120000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

从0011FFFC看起就是

0011FFFC 50 00 40 00 00 00 00 00 00 00 00 00 00 00 00

**下面执行ret ,ret这句等价于 jmp [esp]

                                        add esp,04

这里[esp]=00400055

那么就是 jmp 00400055

           add esp,04

esp=0011FFFC+4以后就是00120000

JMP 00400050

就跳到了CALL下一行指令处,并且ESP这里跟进CALL前是一样的了

          

原文地址:https://www.cnblogs.com/qq32175822/p/3386979.html