147 lines
4 KiB
NASM
147 lines
4 KiB
NASM
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
|