系统调用与函数调用有什么区别?

news2024/11/26 18:28:47

本文我们来聊聊系统调用与普通的函数调用之间的区别。

作为程序员你肯定写过无数的函数,假设有这样两个函数:

void funcB() {}
void funcA() {  funcB();}

函数之间是可以相互调用的,这很简单很happy有没有。

要知道是代码、是函数就可以相互调用,不管你用什么语言写的。

假设funcB是内核中的函数,funcA是你自己写的函数,就像这样:

 

// Linux内核中的函数void funcB() {}
// 你的函数void funcA() { funcB();}

那么funcA应该也能调用funcB(如果funcB可以供外界调用的话)。

有的同学可能会惊呼,我们可以自己编写代码调用操作系统的函数,那岂不是可以直接控制操作系统了?

too yong too simple!

如果我们编写的代码可以直接调用所有的操作系统函数那么从某种程度上讲的确可以说是能控制操作系统,但如果操作系统只允许你调用内核中的有限的几个函数呢?

怎么样,你(应用程序)是不是就被限制住了。

你又会问,操作系统是怎样限制应用程序能调用哪些内核中的函数呢?

实际上单靠操作系统这种软件是没有办法限制应用程序能调用哪些以及多少个内核函数的,因此为施加这种限制必须依靠——硬件。

这里的硬件指的就是CPU。

那么CPU又是怎么施加这种限制的呢?

我们先来看看普通的函数调用,函数调用对应的机器指令是call指令,就像这样:

 

call 0x400410

call指令后的这个地址0x400410就是被调函数的第一条机器指令所在的内存地址。

当CPU执行到这条机器指令时直接跳转到对应的地址继续执行指令,从程序员的角度看就是函数调用。

而如果是我们程序的函数调用操作系统的函数就不允许使用call指令了,而是syscall机器指令(x86_64)。

使用syscall指令调用操作系统函数时也是把相应函数的第一条指令的地址放到syscall之后吗?

显然不是的,因为操作系统系统代码和你的代码都是单独编译以及运行的,你根本就不知道操作系统的某个函数存放在内存的什么位置上,也不应该让你知道,因此使用syscall调用操作系统的函数时我们只能附加一个序号,比如序号0对应操作系统中的A函数、序号1对应操作系统中的B函数等等,这样使用syscall指令时只需要将该序号写入rax寄存器即可,CPU在执行syscall指令时通过读取rax寄存器的值就能知道到底该调用操作系统中的哪个函数了。

可以看到,利用这种机制操作系统限制了应用程序可以调用哪些内核中的函数。

有的同学可能会有疑问,如果一个call指令因为种种原因后面跟上的地址”无意“中指向了一个内核函数的地址,那么CPU执行call指令时会怎样呢?就像这样:

call 0x400410

这里假设0x400410这个地址指向了一个内核函数地址。

很简单,CPU在执行这条指令时会判断出当前进程没有权限访问0x400410这个地址,因此CPU在执行这条指令时会产生异常,该进程会被直接kill掉。

这里列举了Linux在各种处理器上怎样进行系统调用。

图片

看到了吧,syscall和call在使用方法上还是有很大不同的,可以看到call是直接调用的,也就是说应用程序这一层中的函数调用是直接调用的,而syscall其实是间接调用的,即我们调用操作系统中的函数时其实是间接调用的。

除此之外,CPU在执行call指令以及syscall指令时另外一个不同点在于模式的切换。

当CPU执行普通函数时其实是运行在用户态,user mode,在这种模式下CPU不能执行某些特权指令,这也就意味着我们的程序其实是受限的;而当CPU执行syscall开始执行操作系统的代码时会切换到内核态,kernel mode,在这种模式下CPU可以执行任何特权指令,不受任何限制,操作系统才是真正的管理计算机的大boss。

可以看到,当在普通程序中进行函数调用时就是函数调用,而普通函数调用操作系统中的函数时才叫系统调用。

最后再说一点,普通的函数调用所使用的栈全部位于进程的栈区,假设main函数调用funcA函数,funcA调用funcB函数,那么此时的进程内存布局就像这样:

图片

而进行系统调用时当CPU开始执行操作系统的代码时不再基于进程栈区而是会跳转到操作系统某个特定内存区域,该区域作为进程在内核中的栈区,因此也叫做内核栈,每个进程在内核中都有自己的内核栈,因此我们可以看到一个进程其实有两个栈区,一个在用户态一个在内核态。

假设main函数调用funcA,funcA进行系统调用,调用内核中的funcB函数,funcB函数调用内核中的funcC函数,那么此时的内存布局就像这样:

图片

好啦,这个话题就到这里,希望对大家理解操作系统有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/753509.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ABAP 发送特定格式内容的邮件

项目中,经常会有需求,向客户,供应商发送邮件,但是会有一些格式上的要求。 我们一般使用长文本来处理此类需求 举例,客户需要发送一个如下邮件主体内容(带格式) Dear Customer, Attached is y…

相机图像质量研究(2)ISP专用平台调优介绍

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…

洛谷:P5016 龙虎斗 ← NOIP2018 普及组T2

【题目来源】https://www.luogu.com.cn/problem/P5016【题目描述】 轩轩和凯凯正在玩一款叫《龙虎斗》的游戏,游戏的棋盘是一条线段,线段上有 n 个兵营(自左至右编号 1∼n),相邻编号的兵营之间相隔 1 厘米,…

psutil库使用详解

一、背景 在Python的世界里,有一些库因其强大的功能和易用性而备受开发者们的喜爱。今天,我们要介绍的就是其中的一员——psutil库。psutil(python system and process utilities)是一个跨平台的第三方库,用于获取系统运行时的进程和系统利用…

MySQL 事务与存储引擎

目录 一、MySQL事务的概念 二、事务的ACID特点 2.1 原子性 2.2 一致性 2.3 隔离性 2.4 持久性 2.5 事务之间的相互影响 三、Mysql及事物隔离级别 3.1 查询全局事务隔离级别 3.2 查询会话事务隔离级别 3.3 设置全局事务隔离级别 3.4 设置会话事务隔离级别 …

Android自定义圆环进度条/刻度仪表盘(单环单点带动画)

效果图: 1.自定义HeartDashBoardView /*** 刻度仪表盘*/ public class HeartDashBoardView extends View {private static final float START_ANGLE 135f;private static final float MAX_ANGLE 270f;private float progress 0;private float centerX;private float center…

快快快快快快快快快快排

作者简介:დ旧言~,目前大一,现在学习Java,c,Python等 座右铭:松树千年终是朽,槿花一日自为荣。 望小伙伴们点赞👍收藏✨加关注哟💕💕 C语言实现快排☺️ ℹ️…

应届毕业生要如何准备秋招简历?

秋招对于应届毕业生是一个求职的重要渠道,但是很多应届毕业生却不知道要如何制作秋招简历。那么,秋招简历应该如何制作呢?接下来,小编给大家讲一讲简历制作(https://www.jiaobu365.com/)的哪些事&#xff0…

2023 世界人工智能大会(WAIC)人才培养论坛成功举办!

Datawhale论坛 来源:2023 世界人工智能大会(WAIC) 前 言 2023 年 7 月 8 日,“2023世界人工智能大会”(WAIC)落下帷幕。7 月 8 日上午,WAIC 的主要分论坛之一“AIGC时代下的青年开发者人才培养…

什么样的性能测试工具才算是好的工具呢?

一、性能测试工具的特征 调度能力 因为性能测试不可能由一台压力机完成或者说大部分情况下,我们不能不可能由一台压力机来完成,凡是对压力真正有所要求的场景,往往是多台压力机共同施加压力完成性能测试;因此,性能测…

【GitHub】强大的终端录制工具-Terminalizer

Terminalizer 是一个GitHub上优秀的开源项目,目前项目点赞数已达:14k,该项目可以轻松记录下你在命令行的操作,并将录制好的内容输出成 gif 图像或直接分享到网上。 项目开源协议:MIT 项目主开发语言:JavaSc…

Vue计算属性:简化数据处理和视图更新的利器

一、计算属性的基本使用 计算属性:一个特殊属性,值依赖于另外一些数据动态计算出来。🚩🚩🚩计算属性特点:函数内使用的变量改变,重新计算结果返回。💣💣💣注…

uniapp实现聊天消息触,vue3和vue2实现聊天消息触底 scrollTop ,scrollHeight Pc端H5端都适用

uniapp触底SDN链接如下(本人的另一篇博客) uniapp聊天时时触底链接 Pc端 模拟手机端H5 vue3写法 <template><div><!-- 聊天窗体 --><div class"test" id"gundong"><div class"text" v-for"p in chat"&…

Html基础知识学习——兼容问题与解决方法

文章目录 1.计算一定要精确&#xff0c;不要让内容的宽高超出我们设置的宽高&#xff0c;在IE6下内容会撑开设置好的宽高2.元素浮动&#xff0c;宽度需要内容撑开&#xff0c;就给里面的块元素都加浮动3.在ie6.ie7下元素要浮动并在同一行 就给这些元素都加浮动4.注意标签嵌套规…

C# WPF实现动画渐入暗黑明亮主题切换效果

C# WPF实现动画渐入暗黑明亮主题切换效果 效果图如下最近在Bilibili的桌面端看到一个黑白主题切换的效果感觉,挺有意思。于是我使用WPF尝试实现该效果。 主要的切换效果,基本实现不过还存在一些小瑕疵,比如字体等笔刷不能跟随动画进入进行切换。因为Bilibili的客户端是用el…

【算法 -- LeetCode】(018) 四数之和

1、题目 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff1a; …

【Hadoop 01】简介

1 Hadoop 简介 Hadoop适合海量数据分布式存储和分布式计算 Hadoop 3.x的细节优化&#xff1a; Java改为支持8及以上HDFS支持纠删码HDFS支持多NameNodeMR任务级本地优化多重服务默认端口变更 Hadoop主要包含三大组件&#xff1a;HDFSMapReduceYARN HDFS负责海量数据的分布式存…

HttpRunner自动化之跨文件传递变量值输出变量值

跨文件传递&输出变量值 output: 输出变量值,此参数在httprunner2.2版本的时候被 export 代替&#xff0c;跨文件传递参数的功能在httprunner2.2之后不生效。&#xff08;但是实际测试过程中&#xff0c;还可以使用跨文件功能&#xff09; export: 输出变量值,且可以跨文件…