我的通用 isr 存根定义为:
isr_common_stub:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call isr_handler
;call saySomething
pop ebx ; reload the original data segment descriptor
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
;call saySomething
popa ; Pops edi,esi,ebp...
;add esp, 8 ; Cleans up the pushed error code and pushed ISR number
;sti
;call saySomething
;iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
ret ;Return to the caller. Iret and interrupt enabling is handled within caller.
每次中断都会调用此代码,如下所示:
%macro ISR_NOERRCODE 1
global isr%1
isr%1:
cli ; Disable interrupts firstly.
push byte 0 ; Push a dummy error code.
push byte %1 ; Push the interrupt number.
jmp isr_common_stub ; Go to our common handler code.
sub esp, 2 ;Removes 2 bytes from stack
;sti ;Iret enables interrupts again
iret ;Return from interrupt
%endmacro
这段代码适当地调用了外部处理方法,但是从外部处理方法返回后导致gpf中断。
此外,我已将我的 gdt 映射为使用 0 特权级数据和代码描述符(和空描述符)覆盖整个 4G 地址空间。任何帮助表示赞赏。