相关概念
内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序。
用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取。
系统调用的三层皮:API(应用程序接口),中断向量system_call,中断服务程序sys_xyz
内核实现了很多不同的系统调用,进程必须指明需要用哪个系统调用,这需要传递一些参数。其中的系统调用号,是使用eax寄存器传递。
系统调用也需要输入输出参数,例如:实际的值、用户态进程地址空间的变量的地址、包含指向用户态函数的指针的数据结构的地址
system_call是Linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号。
实验:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
首先,我们用库函数exit 调用系统调用实现如下
效果如下
汇编代码调用系统调用的工作过程
exit库函数需要的系统调用参数就一个,即系统调用号。系统调用的参数按照顺序分别放在ebx、ecx、edx、esi、edi及ebp中。
参考网站http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl
sys_exit的系统调用号为1,所以先将其赋给eax。
使用int 0x80触发中断,然后中断处理程序保存现场,进程陷入内核态。
系统调用的返回值使用eax传递。
将eax的值保存到定义的exit中
系统调用的工作机制
应用程序在用户态调用API函数,API将封装的系统调用号及参数保存到eax,ebx等寄存器,读取0x80中断向量触发中断,然后陷入内核态,中断服务程序根据系统调用号调用并执行对应的系统调用函数,系统调用函数执行完毕后将结果存放的eax中并返回给程序,程序返回的用户态。
张何灿 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ”