各种调用方式的笔记
本帖最后由 匿名 于 2016-12-12 20:33 编辑参考C++反汇编与逆向分析技术揭秘,这本书讲的非常好,推荐大家去看看
VC++环境下的调用约定有三种,_cdecl,_stdcall,_fastcall.这三种调用约定解释如下:
_cdecl:C/C++默认调用方式,调用方平衡栈,不定参数的函数可以使用。
_stdcall:被调用方平衡栈,不定参数的函数无法使用。
_fastcall:寄存器方式传参,被调用方平衡栈,不定参数函数无法使用。
所谓的调用方与被调用方理解:
例如:
push 1
push 2
push 3
call xxxxx
add esp,0xC
调用方负责平衡栈意思是当函数结束的时候,也就是call后面直接add esp,push个数*4
被调用方负责平衡栈意思是当函数结束的时候,进行ret 操作,也就是会有ret 4、ret 8之类的。
_cdecl调用方式在函数内没有任何平衡参数操作,而在退出函数后对esp执行加8操作
Show_cdecl(10, 11);
00BF1547push 0Bh
00BF1549push 0Ah
00BF154Bcall Show_cdecl (0BF11D6h)
00BF1550add esp,8//这里平衡参数
_stdcall调用方式在函数内进行retpush参数*4进行堆栈平衡,与_cdecl调用方式相反
Show_stdcall(7, 8);
00BF153Epush 8
00BF1540push 7
00BF1542call Show_stdcall (0BF106Eh)
00BF14EDpop edi
00BF14EEpop esi
00BF14EFpop ebx
00BF14F0add esp,0C0h
00BF14F6cmp ebp,esp
00BF14F8call __RTC_CheckEsp (0BF1145h)
00BF14FDmov esp,ebp
00BF14FFpop ebp
00BF1500ret 8 //这里进行平衡参数
_fastcall:寄存器方式传参,被调用方平衡栈,不定参数函数无法使用
好处是:传递效率高,因为是使用寄存器所以函数结束不用清空栈
坏处是:就只能用两个寄存器ecx,edx大于2就只能乖乖的用栈传递参数
Show_fastcall(22, 33);
00BF1553mov edx,21h
00BF1558mov ecx,16h
00BF155Dcall Show_fastcall (0BF1154h)
return 0;
00BF1562xor eax,eax
例如这个例子:
_fastcall而寄存器比较少,它只使用了ecx,edx保存第一个和第二个参数,其余的放在堆栈操作
Show_fastcall(22, 33,44);
012D1553push 2Ch //大于2个参数只能用栈
012D1555mov edx,21h
012D155Amov ecx,16h
012D155Fcall Show_fastcall (012D11EAh)
012D1499mov esp,ebp
012D149Bpop ebp
012D149Cret 4
页:
[1]