zoukankan      html  css  js  c++  java
  • C++_调用约束

    1、要求

      声明定义处调用约定必须相同

      int __stdcall add(int a, int b);

      int __stdcall add(int a, int b)

      {

         return a + b;

      }

    2、函数调用过程

      假设:A为调用者,B为被调者;A{B};

      函数调用过程可以这么描述:

        (1)先将调用者(A)的堆栈的基址(ebp)入栈,以保存之前任务的信息。

        (2)然后将调用者(A)的栈顶指针(esp)的值赋给ebp,作为新的基址(即被调用者B的栈底)。

        (3)然后在这个基址(被调用者B的栈底)上开辟(一般用sub指令)相应的空间用作被调用者B的栈空间。

        (4)函数B返回后,从当前栈帧的ebp即恢复为调用者A的栈顶(esp),使栈顶恢复函数B被调用前的位置;然后调用者A再从恢复后的栈顶可弹出之前的ebp值(可以这么做是因为这个值在函数调用前一步被压入堆栈)。这样,ebpesp就都恢复了调用函数B前的位置,也就是栈恢复函数B调用前的状态。

    这个过程在AT&T汇编中通过两条指令完成,即:

    3、__cdecl

      __cdecl C Declaration 的缩写,表示 C C++ 默认的函数调用约定。是C/C++MFCX的默认调用约定。

      按从右至左的顺序压参数入栈。A(B,C,D);先进D->C->B

      由调用者把参数弹出栈。切记:对于传送参数的内存栈是由调用者来维护的,返回值在EAX中。因此对于像printf这样可变参数的函数必须用这种约定。

      编译器在编译的时候对这种调用规则的函数生成修饰名的时候,在输出函数名前加上一个下划线前缀,格式为_function。如函数int add(int a, int b)的修饰名是_add

    4__stdcall

      __stdcallStandard Call的缩写,是C++的标准调用方式,当然这是微软定义的标准,__stdcall通常用于Win32 API(可查看WINAPI的定义)

      按从右至左的顺序压参数入栈。

      由被调用者把参数弹出栈。切记:函数自己在退出时清空堆栈,返回值在EAX中。

      __stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的字节数,格式为_function@number。如函数int sub(int a, int b)的修饰名是_sub@8

    5__fastcall

      __fastcall调用的主要特点就是快,因为它是通过寄存器来传送参数的。

      实际上__fastcallECXEDX传送前两个DWORD或更小的参数,剩下的参数仍自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈。

      __fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,格式为@function@number,double multi(double a, double b)的修饰名是@multi@16

      __fastcall__stdcall很象,唯一差别就是头两个参数通过寄存器传送。注意通过寄存器传送的两个参数是从左向右的,即第1个参数进ECX,第2个进EDX,其他参数是从右向左的入栈,返回仍然通过EAX

    6、__pascal

      这种规则左向右传递参数,通过EAX返回,堆栈由被调用者清除

    7、__thiscall

      __thiscallC++类成员函数缺省的调用约定,但它没有显示的声明形式。因为在C++类中,成员函数调用还有一个this指针参数,因此必须特殊处理,thiscall调用约定的特点:

      参数入栈:参数从右向左入栈

      his指针入栈:如果参数个数确定,this指针通过ecx传递给被调用者;如果参数个数不确定,this指针在所有参数压栈后被压入栈。

      栈恢复:对参数个数不定的,调用者清理栈,否则函数自己清理栈。

     8、总结

    调用规则

    入栈顺序

    清栈责任

    __cdecl

    从右到左

    调用者

    __stdcall

    从右到左

    被调用者

    __fastcall

    从右到左(先 EDX、ECX,再到堆栈)

    被调用者

    __pascal

    从左到右

    被调用者

     

  • 相关阅读:
    ICONS-图标库
    图形资源
    vue项目中,如果修改了组件名称,vscode编辑器会在引入修改组件的名字处提示红色波浪线 The file is in the program because:Imported via xxx Root file specified for compilation .
    接口在dev环境报跨域问题(has been blocked by CORS policy:Response to preflight request doesn't pass access control check:No 'Access-Control-Allow-Origin' header ispresent on the requested resource.),qa环境正常
    阿里云occ的图片文件URL用浏览器直接打开无法访问,提示This XML file does noe appear to have any style information associated with it. The document tree is shown below.
    vue 项目使用element ui 中tree组件 check-strictly 用法(父子不互相关联的反显情况)
    高德地图进行线路规划绘制标记点操作(vue)
    vue中实现拖拽调整顺序功能
    2021-01-22 浏览器相关知识
    2021-01-22 js 相关知识点
  • 原文地址:https://www.cnblogs.com/zzw1024/p/10489429.html
Copyright © 2011-2022 走看看