OS-中断,异常和系统调用

来源:互联网 发布:古墓丽影10优化补丁 编辑:程序博客网 时间:2024/05/17 01:58

系统调用(system call)

应用程序主动向操作系统发出的服务请求

异常


非法指令或者其他原因导致当前指令执行失败
如内存出错后的处理请求

中断


来自硬件设备的处理请求
如下图所示,包括中断,异常,和正常的通过函数库调用内核的操作接口。

这里写图片描述

三者不同

  1. 源头不同:
    中断:外设
    异常:应用程序意想不到的行为
    系统调用:应用程序请求操作提供服务
  2. 响应方式:
    中断:异步
    异常:同步
    系统调用:异步或同步
  3. 处理机制:
    中断:持续,对用户应用程序是透明的
    异常:杀死或者重新执行意想不到的应用程序指令
    系统调用:等待和持续

中断和异常处理机制

需要硬件和软件结合处理,其中
硬件需要完成的部分:
1. 在CPU初始化时设置中断使能标志
2. 依据内部或外部事件设置中断标志
3. 依据中断向量调用响应中断服务例程
软件需要完成:
1. 现场保护(编译器)
2. 中断服务处理(服务例程)
3. 清除中断服务标记(服务例程)
4. 现场恢复(编译器)

系统调用

首先看一个函数调用,当用 C 想调用 printf 时,从用户态到内核态是怎样的实现机制。

这里写图片描述

下面再看下系统调用,操作系统服务的编程接口通常由高级语言编写,比如C和C++,程序访问通常是通过高层次的API接口而不是直接进行系统的调用。三种最常用的应用程序编程接口(API)
1. Win32 API用于Windows
2. POSIX API 用于POSIX-based systems(Unix, Linux, Mac OS X的所有版本)
3. Java API 用于JAVA虚拟机(JVM)

一个系统调用和函数调用的例子

  1. 系统调用
    INTIRET 指令用于系统调用:
    系统调用时,堆栈切换和特权级的转化
  2. 函数调用
    CALLRET 用于常规调用,常规调用时没有堆栈切换
    函数调用和系统调用分别启用各自的一套堆栈,前者属于用户态,后者属于内核态,这个好比去银行取钱,必须通过银行的柜台,而不能直接跑到银行密室打开保险箱。

系统调用还是函数调用?

虽然系统调用相比函数调用更安全,但是前者的开销更大,具体表现在:
1. 引导机制
2. 建立内核堆栈
3. 验证参数
4. 内核态映射到用户态的地址空间,比如更新页面映射权限
5. 内核态独立地址空间,TLB