哈喽,我是子牙,一个很卷的硬核男人。深入研究Windows内核、Linux内核、Hotspot源码…聚焦做那些大家想学没地方学的课程:手写操作系统、手写虚拟机、手写模拟器、手写编程语言…
目前我已经做了两个成熟的课程:手写JVM、手写OS,感兴趣的小伙伴可以关注我的公众号【硬核子牙】
今天想跟大家聊什么呢?如图
这是一位学员在学习完函数调用约定那部分内容问我的问题,因为他问的这个问题我想到大家在尝试写OS的时候肯定有诸多问题,而这些问题我遇到过,或者我帮我的学员们解惑过……
所以我准备写系列文章,把我写OS时遇到的,以及我的学员在写OS时遇到的问题,都分享出来。系列文章可关注公众号【硬核子牙】观看,相信你写OS时或者平时研究技术底层时遇到的问题,在这里都能找到答案!因为要做课程比较忙,不定期更新…
今天就函数调用约定与大家分享:
-
什么是函数调用约定
-
函数调用约定有哪些
-
函数调用约定受哪些因素影响
-
Windows、Linux、Mac与调用约定的关系
正片开始,enjoy~
因为要照顾不同基础的小伙伴,对于有基础的小伙伴可以略显啰嗦。那你可以:一,可以不用看这篇文章;二,可以跳到末尾看结论
01
是什么
先做个普及:函数调用约定是什么。因为如果你没有接触过汇编、C语言、C++,你确实没听过这玩意,但是这玩意非常非常非常重要!
如果你想写OS或者研究OS、研究底层技术如虚拟机、搞破解、写游戏外挂……你就得先通过规律确定函数调用约定,才能保证你后续的行为都是正确的!
函数调用约定,见名知意,与函数相关,是一种约定。举例说明
int add(int a, int b, int c);
调用约定就是约束编译器在编译这段代码的时候,对于参数如何处理,对于参数的处理不同,又影响其他行为,什么意思呢?我展开了说
如果你写Java或者Python等高级语言的代码,你可能从来没有关心过这个问题:传递参数的时候,是从右向左传参,函数从左向右传参?是通过寄存器传参,还是通过栈传参,亦或是栈+寄存器传参?如果通过栈传参,就破坏了栈平衡,那如何平栈?
总结来说就是三个问题:
-
传递参数是用寄存器还是栈
-
传递参数是自右向左还是自左向右
-
堆栈平衡由调用方做还是被调用方做
接下来说说不同的调用约定是如何处理这三个问题的
02
有哪些
常见的调用约定有:cdecl、stdcall、fastcall、System V AMD64
先说下cdecl,c declaration,是c/c++在Linux平台下默认的调用约定,即gcc、g++默认的调用约定。其实Mac的默认编译器Clang,默认的调用约定也是这个!不借助寄存器传参,即基于栈传参。传参顺序是自右向左,由调用方平栈
为什么大家都喜欢用cdecl呢?老牌!兼容性好!可移植性好!我写的OS,不论是汇编代码还是C代码,都遵循这个调用约定
stdcall是Windows平台用的比较多的调用约定,跟cdecl的区别就是它是外平栈,即由被调用方平栈
fastcall就比较特别了,也比较复杂:如果参数个数少于两个,就通过寄存器ecx、edx传参,如果参数超过两个,就使用寄存器+栈组合传参,由被调用方平栈
最后一个System V AMD64,一看就是x64用的,可以把它看成fastcall plus,即借助寄存器传参。在x86下叫fastcall,因为x86通用寄存器只有6个,所以只能拿出来两个传参用。在x64下,又新增了r8-r15,所以可以有更多寄存器可以拿来传递参数
因为借助寄存器传参,免去了CPU读写内存的时间,所以快速调用的性能是高于cdecl、stdcall的
可不可以改呢?自然是可以的,语法如下
但是有例外,x64下,Windows、Linux,会忽略修改调用约定,即只支持System V AMD64
03
总结
前面分析得差不多了,这里做下总结:
1、函数调用约定受OS架构、编译器影响
2、Linux平台,默认的编译器,c语言是gcc,c++是g++。x86架构,默认调用约定都是cdecl。x64架构,默认的调用约定是System V AMD64 ABI,约定详情如上所述
3、Windows默认使用的编译器是VC。x86环境下,提供的API默认使用stdcall,程序员编程默认使用cdecl。x64环境下,默认的调用约定是x64调用约定,4个寄存器+栈传参,约定详情如上所述
4、顺便提下Mac,默认编译器是clang,其他跟Linux一样
往期好文推荐
手写操作系统+文件系统开源啦
开发操作系统内核环境搭建
圆梦,手写了一个操作系统
手写操作系统三期
手写OS三期还在招生,三个月时间,八大专题。课程会在合适的节点穿插讲汇编、C语言、操作系统内核、硬件、gcc、elf、Makefile等关联知识,直播教学+课上手敲代码+录播永久观看权限+课后答疑+课后练习+阶段练习,助你真正学会操作系统,对操作系统课程感兴趣,可以关注我的公账号【硬核子牙】咨询了解