操作系统学习笔记(四): 系统调用

本节围绕系统调用展开,主要讲解了系统调用的概念与实现、程序调用与系统调用的不同、系统调用的开销。

概念:

首先看一个标准C库的例子:当我们程序中使用了C库中的printf()函数,实际在底层是在内核态中调用了write()函数。图中右侧则是将程序代码与C库都算到应用程序中,内核提供了一个系统调用接口。从这个例子我们可以得到以下几点:1. 系统调用是操作系统服务的编程接口;2. 系统调用通常由高级语言编写(C或者C++);3. 程序访问通常是通过高层次的API接口(比如C库)而不是直接进行系统调用。其中第三条提到的编程接口库中最常见的三种:1. Windows下的Win32 API;2. POSIX-based系统(包括UNIX、LINUX、Mac OS等)下的 POSIX API;3. JAVA虚拟机中的Java API。

实现:

每个系统调用对应一个系统调用编号。当使用系统调用时,系统调用首先通过软中断的方式进入到内核的中断向量表产生中断,发现是系统调用软中断后转移到系统调用表,系统调用表中记录系统调用编号与具体实现之间的映射关系,根据系统调用编号选取不同的系统调用实现,得到结果之后返回。通过这种方式,用户不需要知道系统调用内部是如何实现的,而只需要设置调用参数和湖区返回结果即可,并且系统调用接口的细节大部分都隐藏函数库后面,通过调用库函数实现。

函数调用与系统调用的不同:

使用的指令不同。系统调用使用INT和IRET,函数调用使用CALL和RET,他们的指令级是完全不同的。具体还有哪些不同呢?我们知道在调用一个函数的时候需要把参数压到堆栈中去,然后转到相应函数去执行,执行的时候从堆栈获取我的参数信息执行,然后返回结果。而对于系统调用来讲,内核是受保护的,为了保护内核,内核与应用程序之间使用不同的堆栈,因此系统调用时会有一个堆栈和特权级的切换,首先切换到内核态,此时可以使用特权指令,并拥有自己的堆栈,执行完后再切换回用户态。而常规调用是没有堆栈切换的。

开销:

系统调用比函数调用更安全,但是开销更大。主要原因就是有一个用户态的切换。具体有以下操作导致开销更大:1. 引导机制,需要引导用户态到内核态的切换;2. 建立内核堆栈,第一次调用时需要创建新的内核堆栈࿱

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值