从x86中断处理程序意外跳转

时间:2015-12-20 02:35:15

标签: assembly x86 gdb stack interrupt

我正在制作我的自定义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会出现在代码中吗? 或者,跳转不是来自代码? 请让我知道为什么会出现这个问题。 谢谢。

0 个答案:

没有答案