您现在的位置是:首页 > 创新技术

中断和异常

智慧创新站 2024-11-28【创新技术】17人已围观

简介中断和异常中断和异常是强制性的执行流的转移,从当前正在执行的任务或程序转移到一个特殊的例程或任务。当硬件发生信号时,便产生中断。中断的产生和正在执行的程序之间是异步的,即中断的产生是随机的。异常是处理器执行指令的过程中发现错误而产生的。处理器的中断和异常处理机制使中断和异常的处理对于应用程序和操作系...

中断和异常

中断和异常是强制性的执行流的转移,从当前正在执行的任务或程序转移到一个特殊的例程或任务。

当硬件发生信号时,便产生中断。中断的产生和正在执行的程序之间是异步的,即中断的产生是随机的。

异常是处理器执行指令的过程中发现错误而产生的。

处理器的中断和异常处理机制使中断和异常的处理对于应用程序和操作系统或可执行程序而言是透明的。

当处理器收到中断信号或者检测到异常的时候,便挂起正在进行的进程或任务,转而去处理中断或异常处理例程。

中断或异常处理例程处理完成后,处理器继续被中断的进程或程序。被中断的程序继续执行。

因此异常处理程序需要记录一些状态信息,以便在异常处理完成后继续执行后面的程序。这些信息也都是通过压栈和出栈进行操作。

为什么当异常发生时会停止当前的程序?

这是因为正常程序的优先级没有异常程序的优先级高。同样对于异常和中断,又有很多优先级可以设置。当一个低优先级的异常发生后,它仍然可以被一个高优先级的异常所打断。这就是异常的嵌套。

异常的优先级有的是固定的,有些则可以被软件来设置。下表显示了各类异常和中断源的优先关系。

只有两种情况例外:无法从产生的异常恢复、中断使当前的程序终止。

异常的处理流程:

当异常发生以后,系统会停止增在发生的程序,转而去访问向量表,然后从向量表中加载异常处理函数的入口地址。

IDT表

int0x80中断的处理

这条指令就是去IDT表中取出中断处理函数,然后执行完后进行下面的代码。

int0x80去哪个中断处理函数去处理?

系统初始化的时候已经设置好的:set_system_gate(0x80,system_call)

define_set_gate(gate_addr,type,dpl,addr)\

__asm__("movw%%dx,%%ax\n\t"\

"movw%0,%%dx\n\t"\

"movl%%eax,%1\n\t"\

"movl%%edx,%2"\

:\

:"i"((short)(0x8000+(dpl13)+(type8))),\

"o"(*((char*)(gate_addr))),\

"o"(*(4+(char*)(gate_addr))),\

"d"((char*)(addr)),"a"(0x00080000))

注释:

%0、%1、%2、%3:0、1、2、3可以看作变量,这些变量在程序的":"之后,程序的两个":",是定义输入、输出项的。针对这段程序这些变量的前面都加了明确的限定,例如"i"(输入项)、"o"(输出项),剩下的"d"(edx的初始值),"a"(eax的初始值)。而0、1、2、3的概念就是指第几个变量,这里输入项、输出向、寄存器初始混合编号;相应的0("i"((short)(0x8000+(dpl13)+(type8)))));1((*((char*)(gate_addr))));2((*(4+(char*)(gate_addr))));3("d"((char*)(addr)));4("a"(0x00080000))

进入汇编程序段后

"d"((char*)(addr))代表把偏移地址addr值放入edx中,一共32位(高16位,低16位)

"a"(0x00080000)代表把0x00080000值放入eax中,一共32位(高16位就是0x0008是段选择符,低16位会被放在edx中的过程偏移低16位代替)

"i"((short)(0x8000+(dpl13)+(type8)))中断或者陷进的属性及dpl,0x8000指示存在,一共32位(高16位为0x0000,低16位放前边说的,会被放入地址的低16位中)

另外两条用于输出

"o"(*((char*)(gate_addr)))

"o"(*(4+(char*)(gate_addr)))放入对应的IDT[]中

movw%%dx,%%axmovw只移动低16位,高16位不变eax中的0x00080000变成了0x008和低16位地址

movw%0,%%dx把第一个参数(%0)低16位放入dx

很赞哦!(79)