函数调用约定
前言
函数调用和被调用之间肯定要规定,如何传递参数,如何恢复栈平衡的问题。
正文
程序运行最开始,main函数肯定是第一个入栈的,其他的函数被调用时相继入栈。
_cdecl
1 |
|
编译自然报错,但是我们看报错信息

之前说到过C语言处理函数在.obj文件下都是加一个_
而c++因为有重载的功能所以还多了参数,除此之外就是_cdecl
_cdecl
的参数入栈 从右到左

堆栈平衡:谁调用谁平衡

所以这种方式能够支持不定量参数。 不定量详情看function1吧,好像写在那里了。
虽然不定量,但是毕竟是从右边开始传递,所以不会出现丢三落四的情况。
_stdcall
因为一般都是_cdecl 所以这玩意比较少见,但是反正能指定。
1 |
|
_stdcall
的参数入栈顺序同为 从右往左
堆栈平衡:由函数自己恢复栈平衡

特色就是windows编程中WINAPI CALLBACK都是_stdcall
的宏
并且生成的函数名会加下划线,后面跟@和参数尺寸

_fastcall
fast看着就想快速
1 |
|
它的特点就是第一个参数由ecx寄存器传递,第二个参数由dex寄存器传递
剩余参数仍然按照入栈顺序 从右到左依次入栈

可以看到俩参数没有通过push指令压入栈中,而是mov给寄存器。
堆栈平衡:由函数自己恢复栈平衡

因为有俩寄存器调用了,所以相对而言会比较快。
当多个形参,比如三个时,add(1,2,3);
3先被push入栈,2和1分别交给寄存器
恢复栈平衡的时候ret 4。 就是只压入了一个3,所以要释放掉。
其他调用
_thiscall 是用于c++中类的访问,用到类的底层时再看
naked call是一个常用的约定,一般也就是实验模式驱动开发
结语
有特殊需求的时候自然会指定函数的调用方式。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Box'Blog!
评论