[bits 32] global interrupts_enable global interrupts_disable global interrupts_load_idt extern interrupts_handle_static_interrupt ; void interrupts_enable( void ) interrupts_enable: push ebp mov ebp, esp sti leave ret ; void interrupts_disable( void ) interrupts_disable: push ebp mov ebp, esp cli leave ret ; void interrupts_load_idt( interrupt_descriptor_table_pointer_t *idt_pointer ) interrupts_load_idt: push ebp mov ebp, esp mov ecx, [ebp+8] lidt [ecx] leave ret ; the handler to ignore interrupts global interrupts_ignore_request interrupts_ignore_request: iret ; void interrupts_handle_request_0x00( ); %macro exception_stub 1 global interrupts_handle_exception_%1 interrupts_handle_exception_%1: mov [interrupt_no], byte %1 jmp int_entry %endmacro exception_stub 0x00 ; IRQs and exceptions would normally collidate, that's why the ; hardware interrupts must be transposed by an offset IRQ_BASE equ 0x20 %macro irq_stub 1 global interrupts_handle_irq_%1 interrupts_handle_irq_%1: mov [interrupt_no], byte IRQ_BASE + %1 ; error push 0x0 jmp int_entry %endmacro irq_stub 0x00 irq_stub 0x01 irq_stub 0x0C int_entry: ; safe state of interrupted code ;pusha push ebp push edi push esi push edx push ecx push ebx push eax ;push ds ;push es ;push fs ;push gs ; call the static C handler with the correct interrupt number ; uint32_t interrupts_handle_interrupt( uint8_t interrupt_no, uint32_t esp ); push esp mov eax, [interrupt_no] push eax call interrupts_handle_static_interrupt ; switch stack mov esp, eax ; restore state (no popa or pusha, we have to align to cpu_state in tasks.h) ;pop gs ;pop fs ;pop es ;pop ds ;popa pop eax pop ebx pop ecx pop edx pop esi pop edi pop ebp ; remove error from the stack add esp, 4 iret interrupt_no: db 0