一、系统调用
1)系统调用可以理解是操作系统为用户提供的一系列操作的接口(API),这些接口提供了对系统硬件设备功能的操作。
举个例子,我们最熟悉的 hello world 程序会在屏幕上打印出信息。程序中调用了 printf() 函数,而库函数 printf 本质上是调用了系统调用 write() 函数,实现了终端信息的打印功能。
2)系统调用是操作系统相关的,因此一般没有跨操作系统的可移植性。
二、库函数
1)库函数可以理解为是对系统调用的一层封装。可以当成应用程序设计人员与系统调用程序之间的一个中间层,通过这个中间层,我们可以用一致的接口来安全的调用系统调用。
三、系统调用意义
- 避免了用户直接对底层硬件进行编程。比如最简单的helloworld程序是将信息打印到终端,终端对系统来说是硬件资源,如果没有系统调用,用户程序需要自己编写终端设备的驱动,以及控制终端如何显示的代码。
- 隐藏背后的技术细节。比如读写文件,如果使用了系统调用,用户程序无须关心数据在磁盘的哪个磁道和扇区,以及数据要加载到内存什么位置。
- 保证系统的安全性和稳定性。要知道用户程序是不能直接操作内核地址空间的,比如一个刚出道的程序猿,让他直接去访问内核底层的数据,那么内核系统的安全性就无法保证。而系统调用的功能是由内核来实现,用户只需要调用接口,无需关心细节,也避免了系统的安全隐患。
四、C库函数与系统调用的区别
1)所有 C 函数库是相同的,而各个操作系统的系统调用是不同的。
2)可以编写代码去覆盖系统调用
3)库函数有可能包含有一个系统调用,有可能有好几个系统调用,当然也有可能没有系统调用,比如有些操作不需要涉及内核的功能。
4)而库函数则是为了人们编程的方便,系统调用是为了方便使用操作系统的接口。
五、从用户调用库函数到系统调用执行的流程。
-
假设用户调用ssize_t write (int fields, cont void *buff, size_t nbytes);库函数。
-
库函数会执行int 0x80中断。因为中断使得进程从用户态进入内核态,所以参数通过
寄存器传送。
- 0x80中断对应的中断例程被称为system call handler。其工作是:
i. 存储大多数寄存器到内核堆栈中。这是汇编代码写的。
ii. 执行真正的系统调用函数――system call service routine。这是C代码。
iii. 通过ret_from_sys_call ()返回,回到用户态的库函数。这是汇编代码。