函数调用约定(Calling Convention)是对函数调用时如何传递参数的一种约定。
函数调用完毕后,ESP寄存器的值需要恢复到函数调用之前的值,从而保证可引用的栈大小不会缩减。而函数调用约定就是解决函数调用后如何处理ESP的问题的。
1、cdecl
cdecl主要是C语言中使用的方式,调用者负责处理栈。
编写简易的代码如下:
#include "stdio.h"
int add(int a, int b){
return (a + b);
}
int main(){
return add(1, 2);
}
在编译生成exe文件前先关闭优化选项才能更好地适用栈帧:
选择Release,生成exe文件,用OllyDbg打开,拉到最上面即可看到主程序:
可以看到,011D101C地址处的“add esp 8”指令,该命令直接清理其压入栈中的两个函数参数(ESP加8即ESP向下移动两个位置,如下图所示,ESP以上位置的数据将被改写而不用特意去释放内存),这样的方式称为cdecl。