美文网首页操作系统 Linux
函数调用约定(Calling convention)

函数调用约定(Calling convention)

作者: 111p1kk | 来源:发表于2019-05-03 11:30 被阅读92次

    一.基本介绍

    函数调用约定,是指当一个函数被调用时,函数的[参数]会被传递给被调用的函数和[返回值]会被返回给调用函数。函数的调用约定就是描述参数是怎么传递和由谁平衡[堆栈]的,当然还有返回值。

    二.函数调用约定

    0x01Windows_x86下的函数调用约定(C)

    -cdecl调用约定
    (c语言默认的函数调用方式)调用函数后,使用

    ASS ESP,XXX
    

    整理栈。
    调用者直接清理压入栈的函数参数。
    好处:它可以像c语言中printf()函数一样,向被调用函数传递长度可变的参数。
    -stdcall调用约定
    (常用于Win32 API,该方式由被调用者清理栈)如果想使用stdcall方式编译源码,只要使用_stdcall关键字即可。
    eg建立函数:

    int _stdcall add(int a, int b)
    

    栈的清理工作由函数最后的

    RETN 8
    

    (该命令含义:RETN + POP 8 字节)来执行。
    好处:被调用者函数内部存在着栈清理代码,代码尺寸小。
    -fastcall调用约定
    (与stdcall类似,但该方式通常使用寄存器传参)头两个参数(从左到右)存入ECX和EDX,余下的参数存入栈中(从右到左)。
    好处:可以实现函数的快速调用(对于CPU,访问寄存器比访问内存快很多)。
    劣处:寄存器在调用函数前若存有重要数据,或者有其他用途,需要将寄存器中的数据先备份。

    0x02WIndows_x64下的调用约定(C)

    -fastcall调用约定
    x64下的调用约定简化了,一律使用_fastcall,前四个参数用ECX, RDX, R8, R9传递,除了这四个外加RAX, R10, R11,其他寄存器都是非易失的。

    0x03LINUX_X64下的函数调用约定

    参数从左到右放入寄存器:RDI, RSI, RDX, ECX, R8, R9。当参数为7个以上时,前6个与前面一样,但后面的依次从“右向左”放入栈中。

    0x04C++调用约定

    -thiscall调用约定
    (c++特有的一种调用约定,用于类成员函数的调用约定)如果参数确定,this指针存放于ECX寄存器,函数自身清理堆栈;如果参数不确定,this指针在所有的参数入栈后再入栈,调用者清理栈。_thiscall不是关键字,程序员不能使用。参数按照从右至左的方式入栈。

    参考:《逆向工程核心原理》——【韩】李承远

    相关文章

      网友评论

        本文标题:函数调用约定(Calling convention)

        本文链接:https://www.haomeiwen.com/subject/fmpanqtx.html