zoukankan      html  css  js  c++  java
  • 四、函数参数的传递规则

    函数参数的传递规则

    函数传递的规则现在一般有两种,一种是WINAPI方式,也就是_stdcall还有一种是_cdecl方式


    _stdcall调用规则:


    (1)参数从右到左进入堆栈
    (2)被调用者在返回前自动清理堆栈


    _cdecl C方式调用规则:


    (1)参数从右到左进入堆栈
    (2)由调用者负责清理堆栈
    生成的程序代码一般会比_stdcall的大。


    C编译器默认采用_cdecl方式,而windows API默认采用_stdcall。

    在windows中,无论哪种方式,返回值都放在eax中,然后返回,外部从eax中得到返回值。


    _cdecl使用的一般过程:
    (1)保持ebp 。ebp总是被我们用来保存这个函数执行前esp的值,执行函数完毕后,用来恢复esp。当然,这个函数的上层函数也是这样做的,所以我们要先把ebp压入堆栈,避免ebp被我们改动。
    (2)保存esp到ebp中
    上面的两步的代码如下:
    push ebp
    mov ebp,esp
    (3)为局部变量申请空间,一般是用sub esp,空间大小 来进行分配,相当于压入堆栈。完成后记得平衡堆栈
    (4)保存其它寄存器的值。ebx、esi、edi压入堆栈,调用完后恢复。
    sub esp,0cch
    push ebp
    push esi
    push edi
    (5)将局部变量区域初始化为0cccccccch,也就是int3指令的机器码。
    lea edi,[ebp-0cch]
    mov ecx,33h
    mov eax,0cccccccch
    rep stos dword ptr [edi]
    (6)做函数要做的事
    (7)恢复ebx、esi、edi、esp、ebp,然后返回
    pop edi
    pop esi
    pop ebx
    mov esp,ebp

    pop ebp
    ret


    对应的c代码:

     1 #include "stdafx.h"
     2 
     3 
     4 int _tmain(int argc, _TCHAR* argv[])
     5 {
     6     void fun(int a,int b);
     7     fun(11,22);
     8     return 0;
     9 }
    10 
    11 void fun(int a,int b)
    12 {
    13     int c=a+b;
    14 }

    对应的函数汇编代码

     1 void fun(int a,int b)
     2 {
     3 00411780  push        ebp  
     4 00411781  mov         ebp,esp  
     5 00411783  sub         esp,0CCh  
     6 00411789  push        ebx  
     7 0041178A  push        esi  
     8 0041178B  push        edi  
     9 0041178C  lea         edi,[ebp-0CCh]  
    10 00411792  mov         ecx,33h  
    11 00411797  mov         eax,0CCCCCCCCh  
    12 0041179C  rep stos    dword ptr es:[edi]  
    13     int c=a+b;
    14 0041179E  mov         eax,dword ptr [a]  
    15 004117A1  add         eax,dword ptr [b]  
    16 004117A4  mov         dword ptr [c],eax  
    17 }
    18 004117A7  pop         edi  
    19 004117A8  pop         esi  
    20 004117A9  pop         ebx  
    21 004117AA  mov         esp,ebp  
    22 004117AC  pop         ebp  
    23 004117AD  ret  

    ..................................

  • 相关阅读:
    WebApi调用及发布
    List<T> 去除重复数据
    C#正则表达式去除XML标签
    SSIS 发送邮件
    域登录验证.net版
    js获取select选中的值
    ionic常见错误
    mac安装brew homebrew
    flutter ios编译报错集
    dart 格式化输出
  • 原文地址:https://www.cnblogs.com/tk091/p/2471947.html
Copyright © 2011-2022 走看看