cdecl调用约定
cdecl调用约定又称为C调用约定,是C语言缺省的调用约定,它的定义语法是:
int average(int n,...) // 不加修饰就是C调用约定 int __cdecl average(int n,...) // 明确指出C调用约定
cdecl调用约定的参数压栈顺序是和stdcall是一样的,参数首先由右向左压入堆栈。所不同的是,函数本身不清理堆栈,调用者负责清理堆栈。由于这种变化,C调用约定允许函数的参数的个数是不固定的,这也是C语言的一大特色。对于前面的function函数,使用cdecl后的汇编码变成:
调用: average(5,1,2,3,4,5); 00C61485 push 5 00C61487 push 4 00C61489 push 3 00C6148B push 2 00C6148D push 1 00C6148F push 5 00C61491 call @ILT+230(_average) (0C610EBh) 00C61496 add esp,18h 00C61499 mov dword ptr [ret],eax
由于参数按照从右向左顺序压栈,因此最开始的参数在最接近栈顶的位置,因此当采用不定个数参数时,第一个参数在栈中的位置肯定能知道,只要不定的参数个数能够根据第一个后者后续的明确的参数确定下来,就可以使用不定参数。
#include
int average(int n,...)
{
va_list arg;
int i = 0;
int sum = 0;
va_start(arg,n); //初始化
for(i=0; i