我正在尝试通过 IDT 处理内核中断。我在 Linux 下的 Intel x86 上工作。
我已经设置了我的 IDT 和我的中断条目,并且我启动了一些测试来查看我的中断处理程序。
当我尝试int $0x0
时,它工作得很好:我的处理程序被调用但是当我尝试一些带有错误代码的异常时,我进入了一个无限循环。
架构如下:
当异常到来时,我的处理程序的第一部分在 ASM 中并调用一个通用的 C 部分。
my_handler.c
void handler(int i)
{
printf("Exception %d caught\n", i);
}
my_handlers.S
common:
pushal
pushl %ds
pushl %es
pushl %fs
pushl %gs
addl $48, %esp // 4 4-bytes segments pushed
// + 8 4-bytes registers (pushal)
` // esp points on exception code
call handler // call the C handler with exception code
subl $48, %esp
popl %gs
popl %fs
popl %es
popl %ds
popal
addl $8, %esp // 4-byte error code + 4-byte exception number
iret
exception_de_handler:
pushl $0 // Fake error code
pushl $0 // interrupt number
jmp common
exception_gp_handler:
// error code is pushed by µproc.
pushl $13 // interrupt number
jmp common
exception_pf_handler:
// error code is pushed by µproc.
pushl $14 // interrupt number
jmp common
如果我尝试运行以下代码:
int* a = 0x0;
*a = 42;
它有效,执行后恢复*a = 42;
但如果我尝试:
int* a = 0x0;
*a = 42;
*a = 1337;
它进入一个无限循环:
Exception 14 caught
Exception 13 caught
Exception 13 caught
Exception 13 caught
Exception 13 caught
.....
Exception 13 caught
Exception 13 caught
Exception 13 caught
.....
为什么处理第一个异常 Page Fault(14) 然后在 General Protection(13) 上循环?
谢谢您的回答。