C语言中函数就是一些代码的集合,实现相对单一的功能;应该有名称、参数、返回值。实际上函数应该是能够从调用程序中接受输入,处理一定的逻辑,并最终能返回到调用程序的一段代码的集合。
本主要讨论windows下C函数如何实现的;主要包括:函数调用约定、参数传递和返回。
调用约定
Windows中默认使用的cdecl调用约定,又叫C调用约定(不加任何修饰就是这种约定)。cdecl的调用约定意味着:
1) 参数从右向左压入堆栈
2) 函数自身不清理堆栈;调用者负责清理,因此这种调用约定允许参数不固定
3) 函数名自动加前导的下划线
例如:函数
Void TestFun(int a,int b);
等价于:
Void __cdecl TestFun(int a,int b);
如果有段代码调用上面的函数,例如:
TestFun(1,2);
那么转变为汇编的就是:
Push 2
Push 1
Call TestFun
Add esp 8 ;2个参数
假设esp的指针在调用函数之前为20,那么上面代码行对应的esp的值为:
Push 2 ;esp =16
Push 1 ;esp=12
Call TestFun ;esp=8
Add esp 8 ;esp=20
其中call指令会修改esp的值,即将函数的返回地址进栈。
WINAPI或stdcall与cdecl不同之处TestFun自己修改堆栈;上面函数的汇编代码是:
Push 2
Push 1
Call TestFun