系统调用

本文详细解析了API与系统调用的区别,指出API可提供用户态或内核态服务,而系统调用通过软中断进入内核。重点介绍了在Linux系统中,用户态进程如何通过int $0x80指令触发系统调用,包括CPU特权级检查、栈切换、系统调用处理程序执行等步骤,深入阐述了系统调用的执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

API和系统调用的区别

  1. 都是函数
  2. API提供用户态服务或者内核态服务
  3. 系统调用通过软中断进入内核态
  4. API可能调用几个系统调用
  5. 系统调用也是一种API

int指令

  1. 用户态进程发出int $0x80指令(老版本Linux中,从用户态切换到内核态的唯一方法)
  2. 系统调用号放入eax寄存器
  3. 根据idtr寄存器找到IDT表,根据0x80找到对应门描述符
  4. 段级检查:将CPU的当前特权级CPL和门描述符中的段选择符的DPL比较(最低两位),CPL≥DPL
  5. 门级检查:将CPU的当前特权级CPL和门描述符的DPL比较,CPL需≤DPL。系统调用门的DPL=3,为了能让CPL=3的用户态进程调用这个异常处理程序
  6. 检查是否发生特权级变化。门描述符中的段描述符的DPL为0,CPL=3,需要进行用户栈到内核栈的更换。从TSS中取出内核栈的SS:ESP完成更换
  7. 将用户栈的SS:ESP压入内核栈(如果特权级没有变化,就不需要压入),将EFLAGS寄存器(标记程序的一些状态的寄存器,比如是否屏蔽中断)压入内核栈,再将被中断进程的CS:EIP压入内核栈
  8. 把门描述符中的段选择符和偏移值放入CS:EIP,CPU就跳转到系统调用处理程序system_call
  9. 调用SAVE_ALL把剩余的寄存器也压入内核栈
  10. 根据EAX中的系统调用号在系统调用表找到对应表项,获取相应的系统调用服务例程的指针,内核就找到要调用的系统调用服务例程
  11. 当从系统调用服务例程结束时,返回值在EAX中,并用返回值更新内核栈中的EAX
  12. 调用RESTORE_ALL恢复保存在内核栈中的寄存器的值
  13. 执行iret回到用户态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值