什么是操作系统接口:
答: 接口函数 调用操作系统中的内部函数, 术语为系统调用, system_call
需要注意的是,应用程序进行系统调用时, 并非直接调用系统中的函数, 而是首先调用一个接口函数, 该接口函数然后才会去调用系统内部的函数。
普通应用程序(应用软件): 程序中会调用一些重要的函数, 这些重要的函数便是 一个个操作系统 提供的接口函数, 接口函数才是提供给应用程序调用操作系统功能的函数。
由于这些接口函数调用的是操作系统内部实现的函数,
区别于应用程序中普通的函数调用,
这种调用系统内部的函数, 便称之为 系统调用, system call
为了将操作系统提供的这些函数的接口规范好, 形成统一的格式:
Posix: portable operating system interface of Unix;
从而方便了应用程序可以在不同的操作系统中运行.
也就是说, 用户写的应用程序, 调用的只是一个接口函数。
起因, 应用程序运行时在内存中,操作系统也在内存中, 为什么应用程序想访问 操作系统的提供的功能函数,
为什么不能 直接去取从内存中去取呢?
答: 操作系统是一个重要的存在,
他掌控了计算机硬件这个国家中,重要的资源, 比方硬件资源, 和用户的密码和数据,
如果,随意的一个应用程序,就可以访问, 捞到用户的密码, 以及任意的掌控这个计算机的资源。
如果,这个应用程序有恶意的行为, 那么 对用户的信息安全,将会造成伤害, 对计算机的硬件资源也会造成伤害。
所以,不可以给应用程序直接访问 系统中的函数和功能。
所以系统调用的作用,
- 不让应用程序 随意的
jump,- 凭什么,使用什么手段不让应用程序
jump- 不让应用程序直接访问, 那么应用程序该如何使用操作系统提供的功能。
不同的程序, 运行时处在不同的级别,
一般系统的程序运行时 是处于核心态中,
普通用户的 应用程序 运行时 处在 用户态中;

计算机对内存的使用,都是一段一段的使用,硬件上实现将内存隔成两个区域:
不同的态,他们所拥有的特权级别不同。
0:内核态处于特权级别, 可以访问任何数据;
3: 用户态权限数值;
数值越低, 权限的级别越高。
数值越大, 权限级别越低,
所以只用当: 目标特权级的数值 >= 当前特权级的数值时, 才可以访问。
而无论什么段, 都需要用到段寄存器;

通过比较 DPL , CPL 的数值, 权限级别低的不可以访问权限级别高的。
只有当DPL >= CPL , 才可以访问内核态。
在系统初始化的时候,
head.S执行的过程中,会针对内核的代码和内核态的数据建立GDT表,其中的DPL 初始化成 0,
在初始化完成后,进入用户态,
执行应用程序的过程中, cs 段寄存器中存放的当前应用程序的特权级别, 此时 CPL = 3, 当通过系统调用时, CPL 会短暂的变成0, 当返回用户态的时候, 又变成3;
而程序每次执行跳转 jmp, 还是 mov 这两个指令时,
都需要访问 GDT 表, 因为访问了段寄存器了, 需要通过段来进入内核态。
访问 GDT 表时候,比较 DPL >= CPL 所对应的数值是否成立。
接口函数,也叫应用程序接口, API(Application Programming Interface), 他将系统内部的函数重新封装了一次, 起到了一个承上启下的作用;
对于应用程序, 接口函数提供给他调用。
对于系统内部函数, 接口函数负责调用他。
接口函数本身并没有 实现 具体的功能, 他起到了作用
- 提供系统调用的中断, 方便进入内核;
- 提供需要调用的功能号, 通过功能号 索引到系统内部需要调用的函数。
首先,普通应用程序调用的是一个接口函数, 不同的接口函数本身会对应不同的调用功能号。
然后,接口函数会调用中断 int 0x80 ,并将该函数调用功能号存放到寄存器eax 中。
通过中断进入内核, 由功能号去定位所需要调用的系统函数。
如图中所示:
应用程序中调用: printf 函数, 调用函数库中的printf 函数:
接口函数: 存在于c 函数库中的 write接口函数,
系统函数: write 接口函数 调用系统内部实现功能的 write 函数,

消息处理机制: