Sure!
Here's asm
Code:
global _isr0
global _isr1
global _isr2
global _isr3
global _isr4
global _isr5
global _isr6
global _isr7
global _isr8
global _isr9
global _isr10
global _isr11
global _isr12
global _isr13
global _isr14
global _isr15
global _isr16
global _isr17
global _isr18
global _isr19
global _isr20
global _isr21
global _isr22
global _isr23
global _isr24
global _isr25
global _isr26
global _isr27
global _isr28
global _isr29
global _isr30
global _isr31
; 0: Divide By Zero Exception
_isr0:
cli
push byte 0
push byte 0
jmp isr_common_stub
; 1: Debug Exception
_isr1:
cli
push byte 0
push byte 1
jmp isr_common_stub
; 2: Non Maskable Interrupt Exception
_isr2:
cli
push byte 0
push byte 2
jmp isr_common_stub
; 3: Int 3 Exception
_isr3:
cli
push byte 0
push byte 3
jmp isr_common_stub
; 4: INTO Exception
_isr4:
cli
push byte 0
push byte 4
jmp isr_common_stub
; 5: Out of Bounds Exception
_isr5:
cli
push byte 0
push byte 5
jmp isr_common_stub
; 6: Invalid Opcode Exception
_isr6:
cli
push byte 0
push byte 6
jmp isr_common_stub
; 7: Coprocessor Not Available Exception
_isr7:
cli
push byte 0
push byte 7
jmp isr_common_stub
; 8: Double Fault Exception (With Error Code!)
_isr8:
cli
push byte 8
jmp isr_common_stub
; 9: Coprocessor Segment Overrun Exception
_isr9:
cli
push byte 0
push byte 9
jmp isr_common_stub
; 10: Bad TSS Exception (With Error Code!)
_isr10:
cli
push byte 10
jmp isr_common_stub
; 11: Segment Not Present Exception (With Error Code!)
_isr11:
cli
push byte 11
jmp isr_common_stub
; 12: Stack Fault Exception (With Error Code!)
_isr12:
cli
push byte 12
jmp isr_common_stub
; 13: General Protection Fault Exception (With Error Code!)
_isr13:
cli
push byte 13
jmp isr_common_stub
; 14: Page Fault Exception (With Error Code!)
_isr14:
cli
push byte 14
jmp isr_common_stub
; 15: Reserved Exception
_isr15:
cli
push byte 0
push byte 15
jmp isr_common_stub
; 16: Floating Point Exception
_isr16:
cli
push byte 0
push byte 16
jmp isr_common_stub
; 17: Alignment Check Exception
_isr17:
cli
push byte 0
push byte 17
jmp isr_common_stub
; 18: Machine Check Exception
_isr18:
cli
push byte 0
push byte 18
jmp isr_common_stub
; 19: Reserved
_isr19:
cli
push byte 0
push byte 19
jmp isr_common_stub
; 20: Reserved
_isr20:
cli
push byte 0
push byte 20
jmp isr_common_stub
; 21: Reserved
_isr21:
cli
push byte 0
push byte 21
jmp isr_common_stub
; 22: Reserved
_isr22:
cli
push byte 0
push byte 22
jmp isr_common_stub
; 23: Reserved
_isr23:
cli
push byte 0
push byte 23
jmp isr_common_stub
; 24: Reserved
_isr24:
cli
push byte 0
push byte 24
jmp isr_common_stub
; 25: Reserved
_isr25:
cli
push byte 0
push byte 25
jmp isr_common_stub
; 26: Reserved
_isr26:
cli
push byte 0
push byte 26
jmp isr_common_stub
; 27: Reserved
_isr27:
cli
push byte 0
push byte 27
jmp isr_common_stub
; 28: Reserved
_isr28:
cli
push byte 0
push byte 28
jmp isr_common_stub
; 29: Reserved
_isr29:
cli
push byte 0
push byte 29
jmp isr_common_stub
; 30: Reserved
_isr30:
cli
push byte 0
push byte 30
jmp isr_common_stub
; 31: Reserved
_isr31:
cli
push byte 0
push byte 31
jmp isr_common_stub
; We call a C function in here. We need to let the assembler know
; that '_fault_handler' exists in another file
extern _fault_handler
; This is our common ISR stub. It saves the processor state, sets
; up for kernel mode segments, calls the C-level fault handler,
; and finally restores the stack frame.
isr_common_stub:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov eax, esp
push eax
mov eax, _fault_handler
call eax
pop eax
pop gs
pop fs
pop es
pop ds
popa
add esp, 8
iret
Here's C
Code:
#include <isr/isr.h>
const char* fault_messages[] =
{
"Division By Zero",
"Debug",
"Non Maskable Interrupt",
"Breakpoint",
"Into Detected Overflow",
"Out of Bounds",
"Invalid Opcode",
"No Coprocessor",
"Double Fault",
"Coprocessor Segment Overrun",
"Bad TSS",
"Segment Not Present",
"Stack Fault",
"General Protection Fault",
"Page Fault",
"Unknown Interrupt",
"Coprocessor Fault",
"Alignment Check",
"Machine Check",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved",
"Reserved"
};
void _fault_handler(reg_dump_t* r)
{
if(r->int_no < 32)
{
puts(" Exception: ");
puts(fault_messages[r->int_no]);
for(;;);
}
}
void isrs_install()
{
idt_set_gate(0,(unsigned)_isr0,0x08,0x8E);
idt_set_gate(1,(unsigned)_isr1,0x08,0x8E);
idt_set_gate(2,(unsigned)_isr2,0x08,0x8E);
idt_set_gate(3,(unsigned)_isr3,0x08,0x8E);
idt_set_gate(4,(unsigned)_isr4,0x08,0x8E);
idt_set_gate(5,(unsigned)_isr5,0x08,0x8E);
idt_set_gate(6,(unsigned)_isr6,0x08,0x8E);
idt_set_gate(7,(unsigned)_isr7,0x08,0x8E);
idt_set_gate(8,(unsigned)_isr8,0x08,0x8E);
idt_set_gate(9,(unsigned)_isr9,0x08,0x8E);
idt_set_gate(10,(unsigned)_isr10,0x08,0x8E);
idt_set_gate(11,(unsigned)_isr11,0x08,0x8E);
idt_set_gate(12,(unsigned)_isr12,0x08,0x8E);
idt_set_gate(13,(unsigned)_isr13,0x08,0x8E);
idt_set_gate(14,(unsigned)_isr14,0x08,0x8E);
idt_set_gate(15,(unsigned)_isr15,0x08,0x8E);
idt_set_gate(16,(unsigned)_isr16,0x08,0x8E);
idt_set_gate(17,(unsigned)_isr17,0x08,0x8E);
idt_set_gate(18,(unsigned)_isr18,0x08,0x8E);
idt_set_gate(19,(unsigned)_isr19,0x08,0x8E);
idt_set_gate(20,(unsigned)_isr20,0x08,0x8E);
idt_set_gate(21,(unsigned)_isr21,0x08,0x8E);
idt_set_gate(22,(unsigned)_isr22,0x08,0x8E);
idt_set_gate(23,(unsigned)_isr23,0x08,0x8E);
idt_set_gate(24,(unsigned)_isr24,0x08,0x8E);
idt_set_gate(25,(unsigned)_isr25,0x08,0x8E);
idt_set_gate(26,(unsigned)_isr26,0x08,0x8E);
idt_set_gate(27,(unsigned)_isr27,0x08,0x8E);
idt_set_gate(28,(unsigned)_isr28,0x08,0x8E);
idt_set_gate(29,(unsigned)_isr29,0x08,0x8E);
idt_set_gate(30,(unsigned)_isr30,0x08,0x8E);
idt_set_gate(31,(unsigned)_isr31,0x08,0x8E);
}
And here's the idt_set_gate
Code:
void idt_set_gate(uint8_t index,uint64_t base,uint16_t sel,uint8_t flags)
{
// Base
g(index).base_low = ((uintptr_t)base & 0xFFFF);
g(index).base_hi = ((uintptr_t)base >> 16) & 0xFFFF;
// Selector
g(index).selector = sel;
// Zero & Flags
g(index).zero = 0;
g(index).flags = flags | 0x60;
}