函数调用约定

1. c调用约定 _cdecl

调用方将参数从右面到左压栈,被调用函数完成后,调用方负责从栈中清除参数。

// c代码
void sum(int a, int b);
int main() {
  sum(10, 20);
}
// 汇编代码
push 20
push 10
call sum
add esp 8
// 或者 编译器预先在栈顶分配了存储空间 
mov [esp + 4], 20
mov [esp], 10
call sum 
这种方式调用sum之后 不需要调整栈指针,GUN(g++和gcc)采用这个技巧。

2. stdcall 调用约定

参数压栈顺序跟cdel一样,只是恢复esp是在被调用者内进行,被调用这采用ret指令。
这种方式的有点是:生成的程序体积稍小 速度稍快, 但是缺点是:对于可变参数的方法不能采用这种方式,只能使用cdecl。

3. fastcall 调用约定

mov edx 20
mov ecx 10
call sum

fastcall是stdcall的变体, 区别是fastcall会使用ecx和edx保存前两个参数。fastcall负责清理esp, 返回的大小减去ecx和edx的大小。

4. c++调用约定

c++静态成员函数就不需要写了,因为他跟普通函数没有区别。
非静态成员函数调用约定,因为需要一个this指针,这个各家编译器有自己的实现,vs系列把this放到ecx里,GUN系列把this作为第一个隐藏参数,this被放到栈顶。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...
    小猪啊呜阅读 4,725评论 1 19
  • 函数调用约定 在C语言中,假设我们有这样的一个函数: int function(int a,int b) 调用时只...
    罗蓁蓁阅读 627评论 0 4
  • 关于 C/C++ 函数调用约定,大多数时候并不会影响程序逻辑,但遇到跨语言编程时,了解一下还是有好处的。 VC 中...
    王守伟阅读 2,450评论 0 2
  • 站在巨人的肩膀上——IDA PRO权威指南阅读笔记 一,窗口 view->open subviews 打开/关闭各...
    SueLyon阅读 14,559评论 0 6
  • 许多年后 又一次梦到你 我知道这并不是噩梦 可为何每次醒来 都是雨天
    精神病人剑十三阅读 183评论 0 0