Защищенный режим процессоров Intel


Программа, которая работает с прерываниями - часть 4


байт физического адреса ; сегмента видеопамяти ; цветного видеоадаптера MONO_LOW EQU 0000 ; мл. байт физического адреса ; сегмента видеопамяти ; монохромного видеоадаптера CRT_SEG EQU 0Bh ; ст. байт физического адреса ; сегмента видеопамяти CMOS_PORT EQU 70h ; порт для доступа к CMOS-памяти PORT_6845 EQU 0063h ; адрес области данных BIOS, ; где записано значение адреса ; порта контроллера 6845 COLOR_PORT EQU 03d4h ; порт цветного видеоконтроллера MONO_PORT EQU 03b4h ; порт монохромного видеоконтроллера STATUS_PORT EQU 64h ; порт состояния клавиатуры SHUT_DOWN EQU 0feh ; команда сброса процессора VIRTUAL_MODE EQU 0001h ; бит перехода в защищённый режим A20_PORT EQU 0d1h ; команда управления линией A20 A20_ON EQU 0dfh ; открыть A20 A20_OFF EQU 0ddh ; закрыть A20 KBD_PORT_A EQU 60h ; адреса клавиатурных KBD_PORT_B EQU 61h ; портов INT_MASK_PORT EQU 21h ; порт для маскирования прерываний EOI EQU 20 ; команда конца прерывания MASTER8259A EQU 20 ; первый контроллер прерываний SLAVE8259A EQU 0a0 ; второй контроллер прерываний ; ------------------------------------------------------------ ; Селекторы, определённые в таблице GDT DS_DESCR = (gdt_ds - gdt_0) CS_DESCR = (gdt_cs - gdt_0) SS_DESCR = (gdt_ss - gdt_0) BIOS_DESCR = (gdt_bio - gdt_0) CRT_DESCR = (gdt_crt - gdt_0) MDA_DESCR = (gdt_mda - gdt_0) ; ------------------------------------------------------------ ; Маски и инверсные маски для клавиш L_SHIFT equ 0000000000000001b NL_SHIFT equ 1111111111111110b R_SHIFT equ 0000000000000010b NR_SHIFT equ 1111111111111101b L_CTRL equ 0000000000000100b NL_CTRL equ 1111111111111011b R_CTRL equ 0000000000001000b NR_CTRL equ 1111111111110111b L_ALT equ 0000000000010000b NL_ALT equ 1111111111101111b R_ALT equ 0000000000100000b NR_ALT equ 1111111111011111b CAPS_LOCK equ 0000000001000000b SCR_LOCK equ 0000000010000000b NUM_LOCK equ 0000000100000000b INSERT equ 0000001000000000b Листинг 3. Демонстрация обработки прерываний и исключений в защищённом режиме для процессора 80286 ----------------------------------------------------------- IDEAL RADIX 16 P286 MODEL LARGE include 'tiny-os.inc' STACK STACK_SIZE DATASEG DSEG_BEG = THIS WORD real_ss dw ? real_sp dw ? real_es dw ? GDT_BEG = $ LABEL gdtr WORD gdt_0 desc_struc <0,0,0,0,0> gdt_gdt desc_struc <GDT_SIZE-1,,,DATA_ACC,0> gdt_idt desc_struc <IDT_SIZE-1,,,IDT_ACC,0> gdt_ds desc_struc <DSEG_SIZE-1,,,DATA_ACC,0> gdt_cs desc_struc <CSEG_SIZE-1,,,CODE_ACC,0> gdt_ss desc_struc <STACK_SIZE-1,,,DATA_ACC,0> gdt_bio desc_struc <B_DATA_SIZE-1,B_DATA_ADDR,0,DATA_ACC,0> gdt_crt desc_struc <CRT_SIZE-1,CRT_LOW,CRT_SEG,DATA_ACC,0> gdt_mda desc_struc <MONO_SIZE-1,MONO_LOW,CRT_SEG,DATA_ACC,0> GDT_SIZE = ($ - GDT_BEG) ; Область памяти для загрузки регистра IDTR idtr idtr_struc <IDT_SIZE,,,0> ; Таблица дескрипторов прерываний IDT_BEG = $ ; ---------------------- Вентили исключений -------------------- idt idt_struc <OFFSET exc_00,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_01,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_02,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_03,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_04,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_05,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_06,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_07,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_08,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_09,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_0A,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_0B,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_0C,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_0D,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_0E,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_0F,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_10,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_11,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_12,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_13,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_14,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_15,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_16,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_17,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_18,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_19,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_1A,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_1B,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_1C,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_1D,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_1E,CS_DESCR,0,TRAP_ACC,0> idt_struc <OFFSET exc_1F,CS_DESCR,0,TRAP_ACC,0> ; --------------- Вентили аппаратных прерываний --------------- ; int 20h-IRQ0 idt_struc <OFFSET Timer_int,CS_DESCR,0,INT_ACC,0> ; int 21h-IRQ1 idt_struc <OFFSET Keyb_int,CS_DESCR,0,INT_ACC,0> ; int 22h, 23h, 24h, 25h, 26h, 27h-IRQ2-IRQ7 idt_struc 6 dup (<OFFSET dummy_iret0,CS_DESCR,0,INT_ACC,0>) ; int 28h, 29h, 2ah, 2bh, 2ch, 2dh, 2eh, 2fh-IRQ8-IRQ15 idt_struc 8 dup (<OFFSET dummy_iret1,CS_DESCR,0,INT_ACC,0>) ; -------------------- Вентиль прерывания -------------------- ; int 30h idt_struc <OFFSET Int_30h_Entry,CS_DESCR,0,INT_ACC,0> IDT_SIZE = ($ - IDT_BEG) CODESEG PROC start mov ax,DGROUP mov ds,ax call set_crt_base mov bh, 77h call clrscr ; Устанавливаем защищённый режим call set_pmode call write_hello_msg ; Размаскируем прерывания от таймера и клавиатуры in al,INT_MASK_PORT and al,0fch out INT_MASK_PORT,al ; Ожидаем нажатия на клавишу <ESC> charin: int 30h ; ожидаем нажатия на клавишу ; AX - скан-код клавиши, ; BX - состояние переключающих клавиш cmp al, 1 ; если <ESC> - выход из цикла jz continue push bx ; выводим скан-код на экран mov bx, 0301h ; координаты вывода call Print_Word pop bx mov ax, bx ; выводим состояние push bx ; переключающих клавиш mov bx, 0306h call Print_Word pop bx jmp charin ; Следующий байт находится в сегменте кода. ; Он используется нами для демонстрации возникновения ; исключения при попытке записи в сегмент кода.


Начало  Назад  Вперед