我正在制作我的自定义8x86 64位操作系统,我对中断处理程序有一些问题。
当我为常见异常和中断添加中断处理程序时,我通过“sti”指令启用了中断。
然后,在启用中断后立即发生“常规保护错误”。
所以,我检查了GDB。
堆栈是
(gdb) bt
#0 kISR::kISRGeneralProtection () at /home/xaliver/WorkSpace/kOdin/kernel64/./ISR.cpp:70
#1 0x000000000000fee8 in ?? ()
#2 0x0000000000202e30 in _kISRTimer ()
Backtrace stopped: frame did not save the PC
奇怪的部分是0xfee8。我使用低于0x10000的内存作为32位保护模式的堆栈。现在,系统处于64位模式,因此该值为空,为“00 00”。
所以,我检查了第2帧,_kISRTimer。
保存的0xfee8的rip是0x202e30。这是_kISRTimer的“iretq”指令。
这是汇编代码。
; #32, Timer ISR
_kISRTimer:
KSAVECONTEXT ; Store the context and change selector to
202dd3: 55 push %rbp
202dd4: 48 89 e5 mov %rsp,%rbp
202dd7: 50 push %rax
202dd8: 53 push %rbx
202dd9: 51 push %rcx
202dda: 52 push %rdx
202ddb: 57 push %rdi
202ddc: 56 push %rsi
202ddd: 41 50 push %r8
202ddf: 41 51 push %r9
202de1: 41 52 push %r10
202de3: 41 53 push %r11
202de5: 41 54 push %r12
202de7: 41 55 push %r13
202de9: 41 56 push %r14
202deb: 41 57 push %r15
202ded: 66 8c d8 mov %ds,%ax
202df0: 50 push %rax
202df1: 66 8c c0 mov %es,%ax
202df4: 50 push %rax
202df5: 0f a0 pushq %fs
202df7: 0f a8 pushq %gs
202df9: 66 b8 10 00 mov $0x10,%ax
202dfd: 8e d8 mov %eax,%ds
202dff: 8e c0 mov %eax,%es
202e01: 8e e8 mov %eax,%gs
202e03: 8e e0 mov %eax,%fs
; kernel data descriptor
; Insert interrupt number to the hander and call the handler
mov rdi, 32
202e05: bf 20 00 00 00 mov $0x20,%edi
call _kCommonInterruptHandler
202e0a: e8 75 e3 ff ff callq 201184 <_kCommonInterruptHandler>
KLOADCONTEXT ; Restore the context
202e0f: 0f a9 popq %gs
202e11: 0f a1 popq %fs
202e13: 58 pop %rax
202e14: 8e c0 mov %eax,%es
202e16: 58 pop %rax
202e17: 8e d8 mov %eax,%ds
202e19: 41 5f pop %r15
202e1b: 41 5e pop %r14
202e1d: 41 5d pop %r13
202e1f: 41 5c pop %r12
202e21: 41 5b pop %r11
202e23: 41 5a pop %r10
202e25: 41 59 pop %r9
202e27: 41 58 pop %r8
202e29: 5e pop %rsi
202e2a: 5f pop %rdi
202e2b: 5a pop %rdx
202e2c: 59 pop %rcx
202e2d: 5b pop %rbx
202e2e: 58 pop %rax
202e2f: 5d pop %rbp
iretq ; Return the event point after interrupt
202e30: 48 cf iretq
我认为没有必要跳过0xfee8。
我还试图删除计时器的中断处理程序。但是,“GPF”出现在其他中断处理程序中。另一个中断处理程序与_kISRTimer相同,但调用函数不同。
你知道为什么GPF会出现在代码中吗? 或者,跳转不是来自代码? 请让我知道为什么会出现这个问题。 谢谢。