API和系统调用的区别
- 都是函数
- API提供用户态服务或者内核态服务
- 系统调用通过软中断进入内核态
- API可能调用几个系统调用
- 系统调用也是一种API
int指令
- 用户态进程发出int $0x80指令(老版本Linux中,从用户态切换到内核态的唯一方法)
- 系统调用号放入eax寄存器
- 根据idtr寄存器找到IDT表,根据0x80找到对应门描述符
- 段级检查:将CPU的当前特权级CPL和门描述符中的段选择符的DPL比较(最低两位),CPL≥DPL
- 门级检查:将CPU的当前特权级CPL和门描述符的DPL比较,CPL需≤DPL。系统调用门的DPL=3,为了能让CPL=3的用户态进程调用这个异常处理程序
- 检查是否发生特权级变化。门描述符中的段描述符的DPL为0,CPL=3,需要进行用户栈到内核栈的更换。从TSS中取出内核栈的SS:ESP完成更换
- 将用户栈的SS:ESP压入内核栈(如果特权级没有变化,就不需要压入),将EFLAGS寄存器(标记程序的一些状态的寄存器,比如是否屏蔽中断)压入内核栈,再将被中断进程的CS:EIP压入内核栈
- 把门描述符中的段选择符和偏移值放入CS:EIP,CPU就跳转到系统调用处理程序system_call
- 调用SAVE_ALL把剩余的寄存器也压入内核栈
- 根据EAX中的系统调用号在系统调用表找到对应表项,获取相应的系统调用服务例程的指针,内核就找到要调用的系统调用服务例程
- 当从系统调用服务例程结束时,返回值在EAX中,并用返回值更新内核栈中的EAX
- 调用RESTORE_ALL恢复保存在内核栈中的寄存器的值
- 执行iret回到用户态
posted @
2021-02-08 22:18
肥斯大只仔
阅读(
73)
评论()
编辑
收藏
举报