§ Объяснение

Очень часто, когда переводится программа в защищенный режим, возникает проблема с IRQ, которые по старинке, находятся по адресам 08-0F для Master и 70-77 для Slave, что совершенно неприемлемо, потому что на векторах 00-1F зарезервированы системные исключения, которые надо тоже как-то обрабатывать. Из-за этого, надо сделать код, который перенаправляет на новые вектора 20-2F. Этот код ниже.

§ Вектора системных исключений

; Offset | INT #     | Description
; -----------+-----------+-----------------------------------
; $0000  | 0x00      | Divide by 0
; $0004  | 0x01      | Trace
; $0008  | 0x02      | NMI Interrupt
; $000C  | 0x03      | Breakpoint (INT3)
; $0010  | 0x04      | Overflow (INTO)
; $0014  | 0x05      | Bounds range exceeded (BOUND)
; $0018  | 0x06      | Invalid opcode (UD2)
; $001C  | 0x07      | Device not available (WAIT/FWAIT)
; -----------------------------------------------------------
; $0020  | 0x08      | Double fault
; $0024  | 0x09      | Coprocessor segment overrun
; $0028  | 0x0A      | Invalid TSS
; $002C  | 0x0B      | Segment not present
; $0030  | 0x0C      | Stack-segment fault
; $0034  | 0x0D      | General protection fault
; $0038  | 0x0E      | Page fault
; $003C  | 0x0F      | ---
; $0040  | 0x10      | x87 FPU error
; $0044  | 0x11      | Alignment check
; $0048  | 0x12      | Machine check
; $004C  | 0x13      | SIMD Floating-Point Exception
; $00xx  | 0x14-0x1F | ---
; -----------------------------------------------------------

§ Код

На всякий случай, если включен APIC — более расширенная версия PIC, нужно его отключить в целях совместимости со старым железом, таким как 386 и ниже.
1push    ax
2mov     ecx, 1Bh
3rdmsr
4and     eax, 0xFFFFF7FF
5wrmsr
Помимо редиректа, на вход подается AX, 16 бит которые обозначают, разрешены ли прерывания IRQ или нет. Например если установлен бит 0, то разрешен IRQ#0 (Timer).
1mov     al, 0x10 + 0x01     ; ICW1_INIT + ICW1_ICW4
2out     0x20, al            ; PIC1_COMMAND
3out     0xA0, al            ; PIC2_COMMAND
4mov     al, 0x20
5out     0x21 , al           ; Master 20h-27h (PIC1_DATA)
6mov     al, 0x28
7out     0xA1, al            ; Slave  28h-2Fh (PIC2_DATA)
8mov     al, 4
9out     0x21, al            ; PIC1_DATA
10mov     al, 2
11out     0xA1, al            ; PIC2_DATA
12mov     al, 0x01            ; ICW4_8086
13out     0x21, al            ; PIC1_DATA
14out     0xA1, al            ; PIC2_DATA
15pop     bx
16not     bx
17mov     al, bl
18out     0x21, al            ; Bitmask LOW (PIC1_DATA)
19mov     al, bh
20out     0xA1, al            ; Bitmask HIGH (PIC2_DATA)
21ret