站点图标 p0ise

函数调用约定

为了能够调用函数,需要有一种公认的方式来传递参数。 如果程序是完全独立的二进制文件,编译器可以自由决定调用约定。 然而在现实中,会使用共享库(例如 libc)以便公共代码可以只存储一次并动态链接到需要它的程序,从而减少程序大小。 在 Linux 二进制文件中,实际上只有两种常用的调用约定:cdecl 用于 32 位,SysV 用于 64 位

cdecl

在 Linux 上的 32 位二进制文件中,函数参数以相反的顺序传入堆栈。 例如以下函数:

int add(int a, int b, int c) {
    return a + b + c;
}

在被调用时,参数会按cba的顺序被压入栈。

SysV

对于64位二进制文件,函数参数先按顺序在一些寄存器中传递:

然后,剩下的参数会以逆序压入堆栈中,就像 cdecl 中一样。

其他约定

只要编译器知道这个惯例是什么,任何传递参数的方法都可以使用。因此,过去有许多调用惯例,现在已经不经常使用了。参见 Wikipedia 的列表。

退出移动版