Win32-API函数调用的约定

函数调用原理:
win32 api的函数调用方式是stdcall,其过程操作如下:


调用函数的代码:

1.调用函数的逻辑代码
2.函数调用代码 
  a.将参数存入栈 (从右向左入栈)
  b.跳转  call 入口地址
    push eip (压入返回地址,即函数调用返回后要执行的下一条指令的地址) 
    mv eip 函数的地址 (将eip设置为被调用函数的地址,执行其代码区指令) 

3.调用函数的逻辑代码


被调用函数的代码:
1.压入函数栈帧
    push ebp(压入旧栈帧的底部)
    mov ebp,esp(设置新栈帧的底部)
    sub esp,xxx(设置新栈帧的顶部)
2.被调用函数的逻辑(如果有返回值的话,存入寄存器)
3.弹出函数栈帧
    add esp,xxx(回收当前栈帧,栈顶指向旧栈帧底部值)
    pop ebp(将旧栈帧底部值位置恢复到ebp)
4.返回 ret
    将eip设置为返回地址(返回到原函数)


由调用函数和被调函数的模拟步骤可以看出:
(addr:005)call ~ (压入栈中的值是:006,把~的地址放入eip)
(addr:006)do sth
上下两指令之间,时间和步骤上是分水岭,距离上可能很远。
(addr:078)push ebp



回忆组成原理知识,一条机器指令的执行过程:取指,译码,执行,写回。每一条机器指令的运行,都会涉及到EIP的变化(这是机器级别的,其操作对汇编级别也不可见)。

call ~ 指令完成的微操作:
1,将当前eip的值(也就是当前指令的地址+1,也就是call~这条指令的所在地+1)放入栈中。
2,把eip从当前值改为被调用函数的首地址。


ret 指令完成的微操作:
1,从栈中取出值,送入eip。


jmp ~ 指令完成的微操作:
1,把eip的值改为~。



你可能感兴趣的:(windows)