Смекни!
smekni.com

Робота в захищеному режимі мікропроцесора (стр. 5 из 5)

out dx,al

mov al,20h

out dx,al

pop dx

pop ax

@99:cmp cpu_type,2 { Если 80286 - разрядность 16, }

jz @l1 { иначе - 32 }

db 66h

@l1:iret

end;

begin

clrscr;

{------Определение значения сегмента кода cs1 процедур,-----}

{------------------описанных в модуле PROT------------------}

cs1:=Seg(int_30h);

excep:=$ff; { Отличное от FFh значение переменной excep }

{ означает номер возникшего при работе программы исключения }

sscan:=0; { Клавиша не нажата }

res:=0; { МП сброшен не был }

{-----------Определение типа микропроцессора----------------}

get_cpu_type(0,cpu_type); { В cpu_type - номер типа МП }

if cpu_type=2 then t:=0 { 16-разрядный МП }

else t:=8; { 32-разрядный МП }

{ Формирование байта доступа прерывания: }

acc_int:=present OR type_int OR t;

{ Формирование байта доступа ловушки: }

acc_trap:=present OR type_trap OR t;

{-----------------Формирование таблицы GDT--------------------}

{ Нуль-дескриптор: }

init_gdt(0,0,0,0,0);

{ Дескриптор первого сегмента кода: }

init_gdt(1,$ffff,lin_adr(cseg,0),acc_code1,0);

{ Дескриптор второго сегмента кода: }

init_gdt(2,$ffff,lin_adr(cs1,0),acc_code,0);

{ Дескриптор сегмента данных: }

init_gdt(3,$ffff,lin_adr(dseg,0),acc_data,0);

{--------Имитация отсутствия сегмента данных в памяти:--------}

{-------------бит P в его дескрипторе равен нулю--------------}

{ gdt[3].acc:=gdt[3].acc and not present;

{ Дескриптор сегмента стека: }

init_gdt(4,0,lin_adr(sseg,0),acc_stack,0);

{ Дескриптор сегмента видеопамяти: }

init_gdt(5,4000-1,lin_adr($b800,0),acc_data,0);

{------Формирование данных регистра GDTR и его загрузка-----}

init_gdtr;

{----Определение селектора (cs_real) и смещения (ofs_ret)---}

{-------------точки возврата в реальный режим---------------}

cs_real:=Cseg;

asm mov ofs_ret,offset ret_r end;

{---------------------Формирование данных-------------------}

{---------для перехода на метку ret_r после сброса МП-------}

{-----------с инициализацией контроллера прерываний---------}

save_ret_real(cs_real,ofs_ret,5);

{------Запрет маскируемых и немаскируемых прерываний--------}

not_int;

{--------------Формирование таблицы IDT-------------------- }

{ Дескрипторы шлюзов обработчиков исключений 0-18: }

init_idt(0,ofs(exc_00),code_sel,acc_trap);

init_idt(1,ofs(exc_01),code_sel2,acc_trap);

init_idt(2,ofs(exc_02),code_sel2,acc_trap);

init_idt(3,ofs(exc_03),code_sel2,acc_trap);

init_idt(4,ofs(exc_04),code_sel2,acc_trap);

init_idt(5,ofs(exc_05),code_sel2,acc_trap);

init_idt(6,ofs(exc_06),code_sel2,acc_trap);

init_idt(7,ofs(exc_07),code_sel2,acc_trap);

init_idt(8,ofs(exc_08),code_sel2,acc_trap);

init_idt(10,ofs(exc_10),code_sel2,acc_trap);

init_idt(11,ofs(exc_0b),code_sel,acc_trap);

init_idt(12,ofs(exc_12),code_sel2,acc_trap);

init_idt(13,ofs(exc_13),code_sel,acc_trap);

init_idt(14,ofs(exc_14),code_sel2,acc_trap);

init_idt(16,ofs(exc_16),code_sel2,acc_trap);

init_idt(17,ofs(exc_17),code_sel2,acc_trap);

init_idt(18,ofs(exc_18),code_sel2,acc_trap);

{ Дескриптор шлюза обработчика прерывания от таймера: }

init_idt($20,ofs(ttim),code_sel,acc_int);

{ Дескриптор шлюза обработчика прерывания от клавиатуры : }

init_idt($21,ofs(keyb),code_sel,acc_int);

{ Дескрипторы шлюзов обработчиков прерываний IRQ2-IRQ7: }

for i:=2 to 7 do

init_idt($20+i,ofs(PIC_1),code_sel2,acc_int);

{ Дескрипторы шлюзов обработчиков прерываний IRQ8-IRQ15: }

for i:=8 to 15 do

init_idt($20+i,ofs(PIC_2),code_sel2,acc_int);

{ Дескриптор шлюза обработчика программного прерывания: }

init_idt($30,ofs(int_30h),code_sel2,acc_trap);

init_idt($32,ofs(int_32h),code_sel2,acc_int);

{-------Сохрание данных регистра IDTR в переменной IDTR-----}

asm

db 0fh,1,0eh { SIDT idtr }

dw idtr_r

end;

{------Формирование данных регистра IDTR и его загрузка-----}

{--------------для работы в защищенном режиме---------------}

init_idtr_p;

(* {--------------Формирование данных регистра IDTR------------}

{---------------для работы в реальном режиме---------------}

init_idtr_r; *)

{----------Программирование контроллера прерываний----------}

{--------------для работы в защищенном режиме---------------}

pic(1);

{-------Сохранение содержимого регистров DS,SS,ES и SP------}

save_sreg;

real_sp:=SPtr;

if cpu_type=2 then

{---------Переход в защищенный режим для МП 80286-----------}

asm { Установка бита PE=1 в регистре MSW: }

db 0fh,01h,0e0h { SMSW AX }

or ax,1

db 0fh,01h,0f0h { LMSW AX }

end else

{-------Переход в защищенный режим для МП 80386 и выше-----}

asm { Установка бита PE=1 в регистре управления CR0: }

db 0fh,20h,0c0h { MOV EAX,CR0 }

db 66h,0dh { OR EAX,1 }

dd 1h

db 0fh,22h,0c0h { MOV CR0,EAX }

end;

asm

push code_sel { Дальний переход на метку @prot }

push offset @prot { для загрузки CS и сериализации }

retf

{----------------Работа в защищенном режиме-----------------}

{---------------Загрузка сегментных регистров---------------}

{---------------соответствующими селекторами----------------}

@prot:

mov ds,data_sel { DS, }

mov ss,stack_sel { SS }

mov es,video_sel { и ES }

{-------------------Вывод на экран строки-------------------}

{---------"Обработка прерываний в защищенном режиме"--------}

{-----------с помощью функций 1 и 4 прерывания 30h----------}

mov ah,1 { Установка маркера: }

mov bx,903h { строка 3, столбец 9 }

int 30h

mov ah,4 { Вывод строки s на экран: }

mov cl,1eh { видеоатрибут, }

mov si,offset s { адрес строки }

int $30

mov ah,1

mov bx,705h

int 30h

mov ah,4 { Функция 4: вывод на экран }

mov si, offset s1 { строки символов s1 }

mov cl,1ch

int 30h

mov ax,301h { Функция 3, подфункция 1: }

mov dx,cs

mov cl,1ch

int 30h { Вывод на экран CS }

mov ax,301h

mov dx,ss

mov cl,1ch { Вывод на экран SS }

int 30h

mov ax,301h

mov dx,ds

mov cl,1ch

int 30h { Вывод на экран DS }

mov ax,301h

mov dx,es

mov cl,1ch

int 30h { Вывод на экран ES }

mov ax,302h { Функция 3, подфункция 2: }

db 0fh,20h,0c2h { MOV EDX,CR0 }

mov cl,1ch

int 30h { Вывод на экран CR0 }

mov ax,302h

db 66h

pushf

db 66h

pop dx

mov cl,1ch

int 30h { Вывод на экран EFLAGF }

mov ah,1

mov bx,510h

int 30h

mov ah,4 { Функция 4: вывод на экран }

mov si, offset s3 { строки символов s3 }

mov cl,1ch

int 30h

mov ah,1

mov bx,511h

int 30h

mov ah,4 { Функция 4: вывод на экран }

mov si, offset s4 { строки символов s3 }

mov cl,1ch

int 30h

{Virabotka zad isklucheniya}

mov ax,cs:[0]

{-------------Разрешение маскируемых прерываний-------------}

sti

{----Ожидание и обработка прерываний до установки семафора----}

{mov ax,cs:[0]}

@wait:

cmp scan,1h

jnz @wait

{int 13}

cmp cpu_type,2

jnz @mov

{----Возврат в реальный режим по сбросу микропроцессора-----}

push code_sel2

push offset reset

retf

{---Подготовка к возврату в реальный режим по команде MOV---}

{---------Установка параметров сегментов DS, SS и ES--------}

{---------------для работы в реальном режиме----------------}

@mov:

(* ARBEITEST an seleron 6 version !!!

push code_sel2

push offset reset

retf

*) cli

mov ds,data_sel

mov ss,data_sel

mov es,data_sel

{---------------Восстановление атрибутов IDT----------------}

{---------------для работы в реальном режиме----------------}

{-------Возврат в реальный режим по команде MOV-------------}

db 0fh,01h,1eh { LIDT idtr_r }

dw idtr_r

db 0fh,20h,0c0h { MOV EAX,CR0 }

db 66h,25h { AND EAX,FFFFFFFEh }

dd 0fffffffeh

db 0fh,22h,0c0h { MOV CR0,EAX }

push cs_real

push ofs_ret

retf

{-----------------Работа в реальном режиме------------------}

{---------------Восстановление регистров после--------------}

{------------------возврата в реальный режим----------------}

ret_r:

xor ax,ax

mov ds,ax

mov ds,[4*60h] { DS, }

mov ss,real_ss { SS, }

mov es,real_es { ES }

mov sp,real_sp { и SP }

end;

if res=0 then

{-------Перепрограммирование контроллеров прерываний--------}

{-------------для работы в реальном режиме------------------}

pic(0)

else

{---------Размаскирование контроллеров прерываний-----------}

{---------------после сброса микропроцессора----------------}

begin

port[$21]:=184;

port[$a1]:=13;

end;

{---Разрешение маскируемых и немаскируемых прерываний---}

en_int;

{-----В случае возникновения исключения вывод его номера-----}

gotoXY(1,20);

{----------Анализ возврата МП из защищенного режима---------}

if res=0 then s:='по команде MOV' else s:='через сброс МП';

writeln('Возврат из защищенного режима выполнен ',s);

writeln('Скан-код нажатой клавиши - ',scan,' - ESC');

end.


5. Результати роботи програми

Розроблена програма реалізує перехід у захищений режим і виводить на екран відомості про тип процесора і виводить вміст регістру флагів і іншу інформацію о системі. Потім реалізується цикл чекання переривання від клавіатури при натисканні клавіші ESC, під час цього обробляються переривання від таймеру і по кожному п’ятому тіку таймеру виконується змінення кольору бордюру. Після завершення циклу чекання натиску клавіші ESC програма реалізує виняткову ситуацію для виникнення 13 переривання, яке обробляється створеним перериванням, яке вилучає із стеку дескриптор помилки і обминає виняткову ситуацію. В кінці програма повертається у реальний режим і відновлює старі таблиці GDT та IDT.


6. Висновки

В даній розрахунково-графічній роботі розроблено програму, що реалізує захищений режим роботи мікропроцесора, обробку апаратних і програмних переривань, засвоєно основні принципи роботи мікропроцесора у захищеному режимі при використанні сегментної моделі пам’яті, порядок обробки переривань, структуру таблиць GDT та IDT.