手写操作系统必掌握基础:函数调用约定

哈喽,我是子牙,一个很卷的硬核男人。深入研究Windows内核、Linux内核、Hotspot源码…聚焦做那些大家想学没地方学的课程:手写操作系统、手写虚拟机、手写模拟器、手写编程语言…

目前我已经做了两个成熟的课程:手写JVM、手写OS,感兴趣的小伙伴可以关注我的公众号【硬核子牙】

今天想跟大家聊什么呢?如图

这是一位学员在学习完函数调用约定那部分内容问我的问题,因为他问的这个问题我想到大家在尝试写OS的时候肯定有诸多问题,而这些问题我遇到过,或者我帮我的学员们解惑过……

所以我准备写系列文章,把我写OS时遇到的,以及我的学员在写OS时遇到的问题,都分享出来。系列文章可关注公众号【硬核子牙】观看,相信你写OS时或者平时研究技术底层时遇到的问题,在这里都能找到答案!因为要做课程比较忙,不定期更新…

今天就函数调用约定与大家分享:

  1. 什么是函数调用约定

  2. 函数调用约定有哪些

  3. 函数调用约定受哪些因素影响

  4. Windows、Linux、Mac与调用约定的关系

正片开始,enjoy~

因为要照顾不同基础的小伙伴,对于有基础的小伙伴可以略显啰嗦。那你可以:一,可以不用看这篇文章;二,可以跳到末尾看结论

01

是什么

先做个普及:函数调用约定是什么。因为如果你没有接触过汇编、C语言、C++,你确实没听过这玩意,但是这玩意非常非常非常重要!

如果你想写OS或者研究OS、研究底层技术如虚拟机、搞破解、写游戏外挂……你就得先通过规律确定函数调用约定,才能保证你后续的行为都是正确的!

函数调用约定,见名知意,与函数相关,是一种约定。举例说明

int add(int a, int b, int c);

调用约定就是约束编译器在编译这段代码的时候,对于参数如何处理,对于参数的处理不同,又影响其他行为,什么意思呢?我展开了说

如果你写Java或者Python等高级语言的代码,你可能从来没有关心过这个问题:传递参数的时候,是从右向左传参,函数从左向右传参?是通过寄存器传参,还是通过栈传参,亦或是栈+寄存器传参?如果通过栈传参,就破坏了栈平衡,那如何平栈?

总结来说就是三个问题:

  1. 传递参数是用寄存器还是栈

  2. 传递参数是自右向左还是自左向右

  3. 堆栈平衡由调用方做还是被调用方做

接下来说说不同的调用约定是如何处理这三个问题的

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等关联知识,直播教学+课上手敲代码+录播永久观看权限+课后答疑+课后练习+阶段练习,助你真正学会操作系统,对操作系统课程感兴趣,可以关注我的公账号【硬核子牙】咨询了解

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值