调用约定 C++对照及汇编详解

来源:互联网 发布:dhcp 端口 67 68 编辑:程序博客网 时间:2024/06/07 13:10

_cdecl(C declration)是C语言函数的默认调用约定规则,也是VS编译器函数默认的调用约定规则,参数从右到左依次push入栈。需要调用者手动平衡栈。使用__cdecl编定规则之后,传递了多少参数和什么类型的参数,被调用者都不会知道,即使不同参数个数和类型都不会产生编译期的错误(PS:以上是指C代码中,C++因为函数名与参数直接关联,所以在编译期是会产生错误)
C++及汇编解析
声明:void __cdecl test(int p1, int p2, int p3)
调用:test(1,2,3)
push 3
push 2
push 1 ;从右到左依次入栈
call test
add esp, 0ch ; 调数外手动平衡栈, 3个参数size为12即0x0c


__stdcall(standard call)是C++的标准调用约定规则,参数也是从右到左依次入栈,如果是调用类成员的话,最后一个入栈的是this指针。与__cdecl不同的是调用者必需严格遵守参数个数,否则编译期将产生错误。并且栈平衡是在被调用者函数中通过ret指令来平衡栈指针的。
声明:void __stdcall test(int p1, int p2, int p3)
调用:test(1,2,3)
push 3
push 2
push 1; 从右到左依次入栈
call test 
; PS: 与__cdecl不同的是少了add esp, 0ch, 因为栈已经在test里面通过ret 0ch 平衡



__fastcall(fast call)是编译器指定的快速调用约定规则。优点是在参数个数较少时,通过寄存器参数传递的方式代替栈参数传递,提高调用的效率。一般fallcall的调用约定规则是将前两个(个数由编译器确定)参数由寄存器传递,其它基本参数还是使用栈指针的方式,和__stdcall 相似
声明:void __fastcall test(int p1, int p2, int p3, int p4)
调用:test(1,2,3,4)
push 4
push 3    ;与__stdcall相似
mov edx,2 
mov ecx,1  ;前两个参数通过寄存器传递
call test  ;栈平衡在test里面平衡



原创粉丝点击