x86中断处理过程

本文聚焦x86中断处理,介绍了x86中中断源,包括外部和软件产生的中断、异常。阐述了CPU与操作系统处理中断的方式,通过中断描述符表(IDT)关联中断与服务例程。还说明了x86通过中断处理实现系统调用的方法,以及如何对IDT进行初始化。

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

了解x86中的中断源

中断、异常在具体的CPU上有不同的表现形式。对于x86而言,它把中断、异常作为特定的两种不同类型来分别处理,但它的实现机制是统一的。

中断interrupts

  • 外部中断External(hardware generated)Interrupts
    串口、硬盘、网卡、时钟、…
  • 软件产生的中断Software generated interrupts
    The INT n指令,通常用于系统调用

异常Exceptions

  • 程序错误 (除零等)
  • 软件产生的异常Software generated exceptions
    INT0,INT3 and BOUND
  • 机器检查出的异常S

了解CPU与操作系统如何处理中断

  • 每个中断或异常与一个中断服务例程(Interrupt Service Routine,简称ISR)关联,其关联关系存储在中断描述符表(Interrupt Descriptor Table,简称IDT)
  • IDT的起始地址和大小保存在中断描述表寄存器IDTR中
    在这里插入图片描述
    如上图,IDT有一个大的数组,每一项称为一个中断门或陷阱门,trap就是我们说的软中断。中断门对应着相应的中断号。一个中断号可以有一个index,可以找到对应的中断门。基于这个中断门可以进一步获取到跟这个中断门相关的段的选择子。
    IDT和GDT结合在一起就可以完成硬件的中断或着是异常和中断服务例程对应的链接关系的建立。
    在这里插入图片描述
    如上图,IDT中的每一项中断门有它相应的格式。这里边最重要的就是段选择子和offset。这样中断服务例程的起始地址就知道了。
    在这里插入图片描述
    如上图,中断向量找到IDT中对应的中断门,取出中断描述子作为index,去全局描述符表GDT中找到对应的段描述符(里边有基地址),再和中断门中的offset相加得到线性地址,从而可以指向ISR中断服务例程。

综上所述,一旦产生中断,CPU可以在硬件层面访问这两个表(这两个表是操作系统建立好的),从而查到对应的中断处理例程(这个例程是操作系统来实现的)。

一旦产生中断,CPU会打断当前正在执行的程序,转去执行中断服务例程,执行完毕之后再返回到当前被打断的程序让这个程序去执行。
这就有一个打断和恢复的过程。

在不同的特权级它的处理方式是不一样的。
在这里插入图片描述
原来在内核态,产生中断之后依然会在内核态,在同一个特权。没有发生任何变化,只是在这个栈上面压了一些寄存器内容,如上图中左侧Stack 1。首先压入被打断的那一刻的寄存器内容error code,然后会压入EIP和CS,这是当前被打断的地址(或当前被打断的下一条地址),第三个是EFLAGS,是当前被打断的时候的标志性内容。

但是如果产生中断的那一刻我们的应用程序正处于用户态执行,中断会切换到内核态。这样发生中断时处于不同的特权级,如图右侧Stack1,Stack2。
在这里插入图片描述
首先看到用户态和内核态使用的是不同的栈。所以说当由于特权级变化产生了中断的时候,除了压刚才说的那些内容之外,还有两个很重要的信息是ESP和SS。这两个内容是当时产生中断的时候,在用户态的栈的地址。

在这里插入图片描述
如上图,当执行完中断服务程序之后,它会通过一个iret指令来完成这个返回。但对于我们通常的程序来说,它是通过ret和retf完成函数的返回。这意味着他们的处理方式是不一样的。

对于没有改变特权级的方式(iret)我们可以看到,他其实是在同一个栈内弹出。根据CS和EIP来跳到当前被打断那个地方继续执行。同时还要恢复它的Eflage的值。
但是对于ret而言,他只是弹出了EIP,跳到当时调的那个下一条指令去执行;对于retf而言,还会把CS弹出来,恢复CS。实行一种远程跳转的功能。这是他们处理不同,当然这里面说到的是,对于没有特级变化的情况的中断的返回,对于特权级变化的中断的返回我们会看到,弹出的东西会更多,EIP CS EFLAG ESP SS。
上面说的都是硬件自动干的部分,还有一部分没有描述的是软件做的,二者结合才能确保整个的中断处理过程的正确的执行。

x86如何通过中断处理来实现系统调用

系统调用可以理解为一种特殊的中断, 它称之为trap 陷入或者叫软中断。

  • 应用程序通过系统调用访问OS内核服务。
  • 如何实现呢
    • 需要指定中断号
    • 使用trap(软中断)
    • 或使用特殊指令(sysenter/sysexit)

能够对中断向量表(中断描述表,简称IDT)进行初始化

通过实验学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值