11.系统调用与API【《链接、装载与库》学习笔记】
系统调用
系统调用(System Call)是应用程序和操作系统内核的接口。
现代操作系统将可能产生冲突的系统资源给保护起来,阻止应用程序直接访问。
Linux系统调用
在x86下,系统调用由0x80中断完成,各个通用寄存器用于传递参数,EAX寄存器用于表示系统调用的接口号。
这些系统调用的C语言形式定义在/usr/include/unistd.h中。
但是,不同系统的系统调用不同,所以一般使用运行库这个中间层。
系统调用原理
特权级与中断
在现代操作系统。通常有两种特权级别:用户模式和内核模式,也称用户态和内核态。操作系统一般通过中断来从用户态切换到内核态。
中断一般有两个属性,一个称为中断号(从0开始),一个称为中断处理程序(Interrupt Service Routine, ISR),不同的中断有不同的中断号,使用中断向量表存储中断号对应的程序。
在中断时,系统调用把系统调用号存入寄存器,到内核态通过读取寄存器获得系统调用号。
在Linux中,用户态和内核态使用的是不同的栈,两者各自负责各自的函数调用,互不干扰。
中断一般执行如下操作:
- 触发中断
- 切换堆栈
- 中断处理程序
Linux新型系统调用机制
Linux操作系统声称一个虚拟动态共享库(Virtual Dynamic Shared Library, VDSO),可以支支持新型系统调用,应对新型的处理器。
Windows API
Windows最底层接口是Windows API。
Windows内核提供了数百个系统调用,(windows把这些系统调用称作系统服务),但是这些系统调用不公开,而在系统调用之上,建立一个API层。
Windows API是以DLL导出函数的形式暴露给应用程序开发者的,把这些头文件、导出库、相关文件和工具一起提供给开发者,并让他们成为SDK。
Windows API被分为几大类别:
| 类别 | DLL |
|---|---|
| 基本服务 | kernel32.dll |
| 图形设备接口 | gdi32.dll |
| 用户接口 | user32.dll |
| 高级服务 | advapi32.dll |
| 通用对话框 | comdlg32.dll |
| 通用控件 | comctl32.dll |
| Shell | shell32.dll |
| 网络服务 | ws2_32.dll |
API与子系统
子系统又称为Windows环境子系统(Environment Subsystem),简称子系统。
子系统实际上又是Windows在API和应用程序之间的一个中间层。但是Windows市场地位逐渐巩固,实际上Windows子系统已经被抛弃。