2008年5月1日星期四
windows下常见的两种调用约定__stdcall、__cdecl——备忘
__stdcall调用:
压栈顺序:从右至左(最后一个参数先进栈)。被调用函数负责平衡堆栈,通常用retn x。
__stdcall的框架看起来是这样的
调用者:
PUSH arg2
PUSH arg1
CALL fun1
被调用者:
PUSH EBP ;保存原来的栈基址
MOV EBP,ESP ;新的基址
……
;ss:[ebp-4]第一个变量
;ss:[ebp+8]是最后一个参数ss:[ebp+C]是倒数第二个参数
……
MOV ESP,EBP
POP EBP
RETN 8
_cdecl 调用:
压栈顺序:从右至左(最后一个参数先进栈)。调用函数负责平衡堆栈,通常用ADD ESP,n。
调用者:
PUSH arg2
PUSH arg1
CALL fun1
ADD ESP,8
被调用者:
PUSH EBP ;保存原来的栈基址
MOV EBP,ESP ;新的基址
……
;ss:[ebp-4]第一个变量
;ss:[ebp+8]是最后一个参数ss:[ebp+C]是倒数第二个参数
……
MOV ESP,EBP
POP EBP
RETN
压栈顺序:从右至左(最后一个参数先进栈)。被调用函数负责平衡堆栈,通常用retn x。
__stdcall的框架看起来是这样的
调用者:
PUSH arg2
PUSH arg1
CALL fun1
被调用者:
PUSH EBP ;保存原来的栈基址
MOV EBP,ESP ;新的基址
……
;ss:[ebp-4]第一个变量
;ss:[ebp+8]是最后一个参数ss:[ebp+C]是倒数第二个参数
……
MOV ESP,EBP
POP EBP
RETN 8
_cdecl 调用:
压栈顺序:从右至左(最后一个参数先进栈)。调用函数负责平衡堆栈,通常用ADD ESP,n。
调用者:
PUSH arg2
PUSH arg1
CALL fun1
ADD ESP,8
被调用者:
PUSH EBP ;保存原来的栈基址
MOV EBP,ESP ;新的基址
……
;ss:[ebp-4]第一个变量
;ss:[ebp+8]是最后一个参数ss:[ebp+C]是倒数第二个参数
……
MOV ESP,EBP
POP EBP
RETN
订阅 博文 [Atom]