bits 32 ; Экспортируем функции для Си global idt_load global isr0, isr1, isr2, isr3, isr4, isr5, isr6, isr7, isr8, isr9, isr10 global isr11, isr12, isr13, isr14, isr15, isr16, isr17, isr18, isr19, isr20, isr21 global irq0, irq1, irq12 ; Импортируем Си-обработчики extern idtp extern isr_handler extern irq_handler ; Инструкция загрузки регистра таблицы прерываний idt_load: lidt [idtp] ret ; Макрос для исключений, КОТОРЫЕ НЕ ПУШАТ код ошибки (подставляем ложный 0) %macro ISR_NOERRCODE 1 idt_stub_isr_%1: push byte 0 ; Ложный код ошибки push byte %1 ; Номер прерывания jmp isr_common_stub %endmacro ; Макрос для исключений, КОТОРЫЕ САМИ ПУШАТ код ошибки %macro ISR_ERRCODE 1 idt_stub_isr_%1: ; Процессор уже напушил код ошибки сам push byte %1 ; Номер прерывания jmp isr_common_stub %endmacro ; Макрос для прерываний от железа (IRQ) %macro IRQ 2 idt_stub_irq_%2: push byte 0 ; Ложный код ошибки push byte %1 ; Номер прерывания (вектор в IDT, например 32) jmp irq_common_stub %endmacro ; Генерируем заглушки с помощью макросов ISR_NOERRCODE 0 ISR_NOERRCODE 1 ISR_NOERRCODE 2 ISR_NOERRCODE 3 ISR_NOERRCODE 4 ISR_NOERRCODE 5 ISR_NOERRCODE 6 ISR_NOERRCODE 7 ISR_ERRCODE 8 ISR_NOERRCODE 9 ISR_ERRCODE 10 ISR_ERRCODE 11 ISR_ERRCODE 12 ISR_ERRCODE 13 ISR_ERRCODE 14 ISR_NOERRCODE 15 ISR_NOERRCODE 16 ISR_ERRCODE 17 ISR_NOERRCODE 18 ISR_NOERRCODE 19 ISR_NOERRCODE 20 ISR_ERRCODE 21 IRQ 32, 0 ; IRQ0 - Таймер IRQ 33, 1 ; IRQ1 - Клавиатура IRQ 44, 12 ; IRQ12 - Мышь (вектор 44) ; Перенаправляем глобальные имена на сгенерированные макросами точки isr0: jmp idt_stub_isr_0 isr1: jmp idt_stub_isr_1 isr2: jmp idt_stub_isr_2 isr3: jmp idt_stub_isr_3 isr4: jmp idt_stub_isr_4 isr5: jmp idt_stub_isr_5 isr6: jmp idt_stub_isr_6 isr7: jmp idt_stub_isr_7 isr8: jmp idt_stub_isr_8 isr9: jmp idt_stub_isr_9 isr10: jmp idt_stub_isr_10 isr11: jmp idt_stub_isr_11 isr12: jmp idt_stub_isr_12 isr13: jmp idt_stub_isr_13 isr14: jmp idt_stub_isr_14 isr15: jmp idt_stub_isr_15 isr16: jmp idt_stub_isr_16 isr17: jmp idt_stub_isr_17 isr18: jmp idt_stub_isr_18 isr19: jmp idt_stub_isr_19 isr20: jmp idt_stub_isr_20 isr21: jmp idt_stub_isr_21 irq0: jmp idt_stub_irq_0 irq1: jmp idt_stub_irq_1 irq12: jmp idt_stub_irq_12 ; <-- Сюда процессор прыгнет при векторе 44 ; Общая точка сборки для Исключений Процессора isr_common_stub: pushad ; Пушит edi, esi, ebp, esp, ebx, edx, ecx, eax mov ax, ds ; Сохраняем сегмент данных push eax mov ax, 0x10 ; Загружаем ядерный сегмент данных в регистры mov ds, ax mov es, ax mov fs, ax mov gs, ax call isr_handler pop eax ; Восстанавливаем оригинальный сегмент данных mov ds, ax mov es, ax mov fs, ax mov gs, ax popad ; Восстанавливаем регистры общего назначения add esp, 8 ; Вычищаем из стека код ошибки и номер прерывания iretd ; Возвращаемся из прерывания ; Общая точка сборки для Прерываний Железа (IRQ) irq_common_stub: pushad mov ax, ds push eax mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax call irq_handler pop eax mov ds, ax mov es, ax mov fs, ax mov gs, ax popad add esp, 8 iretd