Смекни!
smekni.com

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

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ

”ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ”

Розрахунково-графічне завдання №1

з курсу

"Мікропроцесорні системи"

Виконав:

ст. гр. xxxxxxx

xxxxxxxxxxxxx

Перевірив:

xxxxxxxxx

Харків 2006


Зміст

1. Індивідуальне завдання

2. Пояснення до змісту роботи

3. Опис програми

4. Текст програми

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

6. Висновки


1. Індивідуальне завдання

Варіант 16

В захищеному режимі виконати наступні дії:

I. Викликати необхідне згідно із індивідуальним завданням виключення

II. Обробити задане виключення двома засобами:

а) прибравши причину виключення;

б) пропустивши команду, що визвала виключення.

III. Обробити задане зовнішнє переривання.

2. Пояснення до змісту роботи

Для виконання завдання необхідно виконати наступні дії:

1) розробити дескриптори усіх необхідних сегментів пам’яті і сформувати з них глобальну дескрипторну таблицю GDT.

2) за допомогою регістра GDTR задати базову адресу і розмір таблиці GDT;

3) розробити дескриптори усіх шлюзів, сформувати з них таблицю IDT.

4) за допомогою регістра IDTR задати базову адресу і розмір таблиці IDT;

5) сформувати дані для повернення в реальний режим;

6) заборонити масковані і немасковані переривання;

7) перевести мікропроцесор у захищений режим;

8) виконати в захищеному режимі дії, задані індивідуальним завданням;

9) повернутися в реальний режим;

10) дозволити масковані і немасковані переривання.

Для розуміння принципів програмування роботи в захищеному режимі необхідно розуміти його особливості. Захищений режим має такі особливості роботи з перериваннями (порівнюючи з реальним режимом):

1) вводиться новий тип переривань – виключення;

2) замість дальніх адрес в таблиці переривань використовуються дескриптори шлюзів;

3) таблиця переривань може знаходитися в будь-якому місці пам’яті.

Виключення поділяються на три типи:

- Помилка (trap);

- Пастка (fault);

- Аварія (abort).

Помилка – це виключення, що виникає в ситуації помилкових дій програми й припускається, що таку помилку можна виправити. Виконання програми продовжується починаючи із команди, при якій виникло виключення.

Пастка – це виключення, що виникає відразу після виконання команди. Виконання програми продовжується із наступної команди,що йде за командою на якій виникло виключення. На пастках строїться механізм відладки програм.

Аварія – це виключення, що не дозволяє продовжити виконання перерваної програми і сигналізує про серйозні порушення цілісності системи.

3. Опис програми

Для написання програми для виконання разрахункового завдання, скористались модулем PROT і програмою P_INT, що поставляються разом із індивідуальним завданням. В модулі PROT містяться основні необхідні константи і функції для створення власних таблиць GDT та IDT, для переходу в захищений режим, містяться також заглушки для всіх апаратних і програмних переривань. Програма P_INT містить перевизначення необхідних для роботи, або заданих за індивідуальним завданням переривань, в ній задається вміст таблиць GDT та IDT (в ній визначаються селектори заглушок, або необхідних переривань, на необхідних місцях), програма реалізує перехід в захищений режим, імітує виникнення програмного переривання, а також реалізує вічний цикл, до виникнення апаратного переривання. Після цього реалізується вихід до реального режиму, шляхом скидання мікропроцесору (не працює на нових моделях мікропроцесорів) або шляхом відновлення старої GDT та IDT, і повернення до реального режиму. Нами було додано необхідні по індивідуальному завданню апаратне і програмне переривання, і реалізовано виключну ситуацію для їх виникнення.

4. Текст програми

{----Модуль содержит константы, типы переменных, переменные,----}

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

unit prot;

interface

uses crt;

const

hex_tabl:array[0..15] of char='0123456789ABCDEF';

s2:string='Run time error: исключение ';

{--------------Селекторы дескрипторов сегментов---------------}

code_sel =$08; { кода программы, }

code_sel2 =$10; { кода модуля PROT, }

data_sel :word =$18; { данных, }

stack_sel :word =$20; { стека, }

video_sel :word =$28; { видеопамяти, }

mem_sel :word =$30; { расширенной памяти, }

{-----------------Биты байтов доступа сегментов---------------}

present =$80; { P=1 : сегмент есть в памяти }

nosys =$10; { S=1 : сегмент несистемный }

exe =$08; { E=1 : сегмент выполняемый }

down =$04; { ED=1: сегмент расширяется вниз }

wr_ena =$02; { W=1 : разрешена запись в сегмент }

rd_ena =$02; { R=1 : разрешено чтение из сегмента }

{---------Значения поля TYPE системных дескрипторов-----------}

type_int =$06; { шлюза прерывания для 80286 }

type_trap =$07; { шлюза исключения для 80286 }

type_TSS =$01; { сегмента TSS }

type_call =$04; { шлюза вызова }

type_task =$05; { шлюза задачи }

{-----------------Байт доступа сегмента кода------------------}

acc_code=present OR nosys OR exe OR rd_ena;

acc_code1=present OR nosys OR exe ;

{----------------Байт доступа сегмента данных-----------------}

acc_data=present OR nosys OR wr_ena;

{----------------Байт доступа сегмента стека -----------------}

acc_stack=present OR nosys OR wr_ena OR down;

{-----------------Байт доступа шлюза задачи-------------------}

acc_task =present OR type_task;

type

{-------------Структура дескриптора таблицы GDT---------------}

t_gdt=record

lim_l, { граница сегмента (биты 15-0) }

base_l :word; { базовый адрес сегм. (биты 15-0) }

base_h, { базовый адрес сегм. (биты 23-16) }

acc, { байт доступа }

lim_h, { G,D,0,X,граница сегм. (биты 19-16) }

base_hh:byte { базовый адрес сегм. (биты 31-24) }

end;

{-------------Структура дескриптора таблицы IDT---------------}

t_idt=record

off_l, { смещение (биты 15-0) }

sel :word; { селектор }

par, { число параметров }

acc :byte; { байт доступа }

off_h :word { смещение (биты 31-16) }

end;

{---------------Структура регистров GDTR и IDTR---------------}

t_dtr=record

lim :word; { граница и }

base :longint; { базовый адрес таблицы }

end;

{-----------------Структура TSS для МП 80286------------------}

t_tss_286=record

link, { селектор возврата }

sp0,ss0, { указатель стека кольца 0 }

sp1,ss1, { указатель стека кольца 1 }

sp2,ss2, { указатель стека кольца 2 }

ip,flags,ax,cx,dx,bx,sp,bp, { регистры }

si,di,es,cs,ss,ds,ldtr { микропроцессора }

:word;

end;

{--------------Структура TSS для МП 80386 и выше--------------}

t_tss_386=record

link, { селектор возврата }

esp0,ss0, { указатель стека кольца 0 }

esp1,ss1, { указатель стека кольца 1 }

esp2,ss2, { указатель стека кольца 2 }

cr3,eip,eflags,eax,ecx,edx,ebx, { регистры }

esp,ebp,esi,edi,es,cs,ss,ds,fs,gs,ldtr{ МП }

:longint;

bit_t, { бит ловушки задачи }

adr_BKVV:word; { смещение БКВВ }

Sys_inf, { поле для системной информации }

BKVV:longint; { БКВВ }

byte_end:byte; { байт завершения TSS }

end;

var

gdt:array[0..15] of t_gdt; { Таблица GDT }

idt:array[0..$32] of t_idt; { Таблица IDT }

gdtr, { Содержимое GDTR }

idtr, { Содержимое IDTR для работы в защищенном режиме }

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

:t_dtr;

ofs_ret, { Смещение и }

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

ofs_ret_mov, { Смещение метки ret_mov: }

cs_prot, { Селектор регистра CS в защищенном режиме }

cs1, { Значение сегмента кода модуля PROT }

{ Переменные для хранения значений регистров: }

real_ss, { SS, }

real_es, { ES и }

real_sp:word; { SP }

scan, { Скан-код нажатия клавиши }

cpu_type, { Номер типа микропроцессора }

res, { Признак сброса МП }

rm1, { Содержимое регистров маски 1-го }

rm2, { и 2-го контроллеров прерывания }

excep, { Номер исключения }

acc_int, { Байт доступа прерывания }

acc_trap, { Байт доступа ловушки }

t:byte; { Признак разрядности МП: T=0 - 16; T=8 - 32 }

function lin_adr(seg,off:word):longint;

function hex(p:longint):string;

function hw(p:word):string;

procedure init_gdt(i:byte;limit,base:longint;acces,

procedure init_idt(i:byte;p_off,p_sel:word;acces:byte);

procedure pic(mode:byte);

procedure init_gdtr;

procedure init_idtr_p;

procedure init_idtr_r;

procedure save_ret_real(seg,ofs:word;byte_shut:byte);

procedure not_int;

procedure en_int;

procedure set_unr(base,limit:longint;kseg,byte_6h:byte);

procedure save_sreg;

procedure reset;

procedure test_wr;

procedure init_tss_286 (var tss:t_tss_286; cs,ds,es,

ofs_task,ofs_task_stack,flags:word);

procedure init_tss_386 (var tss:t_tss_386; cs,ds,es,

ofs_task,ofs_task_stack,eflags:word);

procedure get_cpu_type(inf:byte;var cpu:byte);

procedure exc_00;

procedure exc_01;

procedure exc_02;

procedure exc_03;

procedure exc_04;

procedure exc_05;

procedure exc_06;

procedure exc_07;

procedure exc_08;

procedure exc_10;

procedure exc_11;

procedure exc_12;

procedure exc_13;

procedure exc_14;

procedure exc_16;

procedure exc_17;

procedure exc_18;

procedure PIC_1;

procedure PIC_2;

procedure keyb;

procedure int_30h;

procedure int_30hr;

procedure int_32h;

implementation

{------Преобразование логического адреса в линейный адрес-----}

function lin_adr;

begin

lin_adr:=longint(seg) shl 4+off

end;{lin_adr}

{-------------Преобразование данных в 16-ричную форму---------}

function hex(p:longint):string;

var s:string;

begin

s:='h';

repeat

s:=hex_tabl[p and $f]+s;

p:=p shr 4

until p=0;

hex:=s

end;{hex}

function hw(p:word):string;

var

i:byte;

s:string;

begin

s:='';

for i:=0 to 3 do begin

s:=hex_tabl[p and $f]+s;

p:=p shr 4

end;

hw:=s

end;{hw}

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

procedure init_gdt(i:byte;limit,base:longint;acces,

byte_6h:byte);

begin

with gdt[i] do begin

lim_l :=limit;

base_l :=base;

base_h :=base shr 16;

acc :=acces;

lim_h :=limit shr 16 or byte_6h;

base_hh:=base shr 24;

end

end; {init_gdt}

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

procedure init_gdtr;

begin

gdtr.lim:=sizeof(gdt)-1;

gdtr.base:=lin_adr(seg(gdt),ofs(gdt));

asm

db 0fh,01h,16h { LGDT gdtr: }

dw gdtr { загрузка атрибутов GDT в GDTR из gdtr }

end

end; {init_gdtr}

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

procedure init_idt(i:byte;p_off,p_sel:word;acces:byte);

begin

with idt[i] do begin

off_l:=p_off;

sel:=p_sel;

par:=0;

acc:=acces;

off_h:=0

end

end; {init_idt}

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

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

procedure init_idtr_p;

begin

asm

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

dw idtr_r { Сохранение атрибутов IDT в idtr_r }

end;

idtr.lim:=sizeof(idt)-1;

idtr.base:=lin_adr(seg(idt),ofs(idt));

asm

db 0fh,01h,1eh { LIDT idtr: }

dw idtr { Загрузка атрибутов IDT в IDTR из idtr }

end;

end;{init_idtr_p}

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

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

procedure init_idtr_r;

begin

idtr_r.lim:=$3ff; { размер таблицы векторов, }