神奇的汇编(三)

来源:互联网 发布:结对编程 图片 编辑:程序博客网 时间:2024/05/05 14:04

这一节说的主要是函数

在汇编中一定也有函数

它叫子程序

它用

      子程序名 proc 语言类型 可视区域 参数 类型

        。。。  。。。

      子程序名 endp

 

来定义的

调用它也很简单 直接invoke就可以了

 

但是想c中一样 要调用它一定少不了声明 不声明就调用一定会出错

 

声明它的方法也蛮简单

     函数名 proto 语言类型 可视区域 参数 类型

就可以了,通常它会放inc里面被include进来

 

调用和使用它看起来简单,其中也隐藏这不少秘密

在调用过程中最需要注意的恐怕是这个语言的类型,这个是调用方和被调用方的一个协定,

即如何传参数,如何保存堆栈平衡

 

对于参数,通常在call的时候会将参数一个一个的压入堆栈中,如果是pascal的调用规范则会从左往右传参数

但是其它stdcall和c的则会从右往左传参数,在压了这么多参数后,当调用完成时候,除了c会由调用方来清理这

些参数外,其它的常用方式则会由被调用者来处理这个清理。

 

在调用函数的时候,调用方会做如下几个事情

1.将参数一一压入栈中

2.将返回地址压入栈中

 

而被调用方将需要做这么做

1.将当前的EBP压入栈中保存

2.将当前的ESP赋予EBP,这样当前的EBP就直接指向原来的EBP

3.通过减ESP的值来给函数的局部变量分配空间

 

在函数结束的时候,通常会调用

leave

ret

 

leave=   move esp ebp

              pop ebp

              将堆栈栈顶回到ebp的位置,然后将原来的ebp还原

ret   =    pop eip

              将返回地址载入eip

 

做了这个就完全还原了堆栈,当然如果是被调用方需要清理参数,那么它需要将esp在ret后继续上移(向栈底方向),

通常是加上 参数个数*4的地址,这个时候可以简单的在ret 后面加上这个数。

如  ret 8 相当于清理2个参数