实验4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
姓名:李冬辉
学号:20133201
注: 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
系统调用有关内容
1、什么是系统调用 :操作系统为用户态进程与硬件设备进行交互提供了一组接口。
2、用户态、内核态、中断和系统调用打交道的方式是通过库函数的方式,库函数将系统调用给封装起来了
3、linux系统下如何区分内核态与用户态
在内核态:cs:eip可以是任意的地址,4G的内存地址空间
在用户态:cs:eip只能访问0x00000000—0xbfffffff的地址空间
4、系统调用的三层皮:xyz、system_call和sys_xyz
第一层:API
第二层:中断向量对应的
第三层:系统调用有不同种类的服务程序
5、系统调用的意义:
(1)把用户从底层的硬件编程中解放出来
(2)极大地提高了系统的安全性
(3)使用户程序具有可移植性
API与系统调用
应用编程接口(application program interface, API)和系统调用是不同的。
- API只是一个函数定义
- 系统调用通过软中断向内核发出一个明确的请求
Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系统调用)。
- 一般每个系统调用对应一个封装例程
- 库再用这些封装例程定义出给用户的API
Libc库定义的一些API引用了封装例程(wrapper routine,唯一目的就是发布系统调用)
- 一般每个系统调用对应一个封装例程
- 库再用这些封装例程定义出给用户的API
不是每个API都对应一个特定的系统调用。
- API可能直接提供用户态的服务
- 一个单独的API可能调用几个系统调用
- 不同的API可能调用了同一个系统调用
返回值
- 大部分封装例程返回一个整数,其值的含义依赖于相应的系统调用
- -1在多数情况下表示内核不能满足进程的请求
应用程序、封装例程、系统调用处理程序、系统调用服务例程之间的关系
使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
选出系统调用号为64的系统调用sys_getppid(),该系统调用用于返回当前进程的父进程进程号数
函数getppid()是glibc对系统调用sys_getppid的封装,用于获取当前进程的父进程的进程号。sys_getppid系统调用号为64.在用户态时候,如果用户调用了getppid(),系统会产生一中断,进入到了内核态执行sys_getppid。getppid()的功能是返回当前进程的父进程的ID,它本身是不能完成的,必须请求操作系统服务即sys_getppid,让操作系统把当前进程的ID告诉给getppid()。
实验截图:
总结:
系统调用的工作机制:
1、应用程序在用户态调用API。
2、API函数将自己对应的系统调用号以及从应用程序得到的参数保存到寄存器中,并触发软中断,使应用程序陷入内核态。
3、system_call()函数根据传入的系统调用号在系统调用列表中查找对应的内核函数,/3、根据寄存器中保存的参数调用该内核函数。
4、内核函数执行完毕之后将执行结果存放到eax寄存器中。
5、中断处理程序执行完毕之后返回,将应用程序带回用户态。
6、被调用的API在最后阶段返回eax中的值并结束API调用。