10/29/2007

_stdcall, _cdecl,_pascal and _fastcall --- calling conventions

1.如果函数func是__cdecl(默认调用方式),调用时情况如下
int main()
{
//参数从右到左压栈
push 4
push 3
push 2
push 1
call func
add esp 0x10 //调用者恢复堆栈指针esp,4个参数的大小是0x10(4x4)
}

2.如果函数func是__stdcall,调用时情况如下
int main()
{
//参数从右到左压栈
push 4
push 3
push 2
push 1
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x10"
}

3.如果函数func是__pascal,调用情况如下
int main()
{
//参数从左到右压栈
push 1
push 2
push 3
push 4
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x10"
}

3.如果函数func是__fastcall,调用情况如下
int main()
{
//参数先用ecx, edx, eax传递,然后再压栈
//不进栈
//(不知为什么,帮助中写的是从左到右传递的,
//是不是错了,还是BCB6和BCB5的不一样)
push 4
mov ecx 3
mov edx 2
mov eax 1
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x04",
//因为只进栈一个参数,其余用寄存器传递,所以用ret 0x04恢复
}

没有评论: