共通の 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 をマップして、4G アドレス空間全体を 0 特権レベルのデータとコード記述子 (およびヌル記述子) でカバーするようにしました。どんな助けでも大歓迎です。