实验四:使用库函数 API 和 C 代码中嵌入汇编代码两种方式使用同一个系统调用
系统调用
- 系统调用的库函数就是读者使用的操作系统提供的API(应用程序编程接口),API只是函数定义。系统调用是通过软中断向内核发出了中断请求,int指令的执行就会触发一个中断请求。Libc库函数定义的一些API内部使用了系统调用的封装例程,其主要目的是发布系统调用,使程序员在写代码时不需要用汇编指令和寄存器 传递参数来触发系统调用。一般每个系统调用对应一个系统调用的封装例程,函数库再用这些封装例程定义出给程序员调用的API,这样把系统调用最终封装成方便程序员使用的库函数。
- 系统调用的意义:把用户从底层的硬件编程中解放出来、极大地提高系统的安全性、使用户程序具有可移动性。
- 如下图所示,User mode表示用户态,kernel mode表示内核态。xyz()就是一个API函数,是系统调用对应的API,其中封装了一个系统调用,会触发int $0x80的中断,对应system_call内核代码的起点,即中断向量0X80对应的中断服务程序入口,内部会有sys_xyz()系统调用处理函数,执行完sys_xyz()后会ret_from_sys_call,这里是进程调度最常见的调度时机点。如果没有发生进程调度,就会执行iret再返回到用户态接着执行。系统调用的3层机制分别为xyz(),system_call和sys_xyz()。
实验过程
-
选择4号 write 系统调用
-
使用库函数API进行系统调用
-
运行结果
-
使用内嵌汇编代码触发系统调用
-
运行结果
分析与总结
本次实验学习了在C语言中使用汇编嵌入方式使用系统调用,对于系统调用有了更深的理解
- 一个API可能只对应一个系统调用,也可能内部由多个系统调用实现,一个系统调用也可能被多个API调用。
- 系统调用的三层机制分别为xyz(),system_call,sys_xyz()。
- 内核通过给每个系统调用一个编号来区分,即系统调用号,将API函数xyz()和系统调用内核函数sys_xyz()关联起来