Організація роботи мiкропроцесора в захищеному режимi, страница 8

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

На рис. 4.6 зображена схема формування лiнiйної (фiзичної) адреси, на якій не показанi моменти завантаження i використання дескрипторного регiстра.

Формування дескpиптоpiв сегментiв для GDT розглянемо на прикладi фрагментiв програми P_MODE, яка для цiєї мети використовує константи, типи, функцiї i процедури модуля PROT.

 


                      Рис. 4.6. Формування лінійної адреси

Структура дескриптора таблицi GDT у вiдповiдностi з форматом дескриптоpа сегмента пpедставлена у виглядi запису наступного типу (модуль PROT):

t_gdt=record                                                                   { Структура дескриптора GDT: }

     lim_l  :word;                                                               { гpаниця сегмента (бiти 15-0); }

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

base_h :byte; { базова адреса сегмента (бiти 23-16);}

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

     lim_h  :byte;                                                            { G, D, 0, X, гpаниця (бiти 19-16); }

base_hh:byte; { базова адреса сегмента (бiти 31-24)}

end;

4.2.4. Формування дескpиптоpiв сегментiв

Значення окремих бiтiв байта доступу у вiдповiдностi з рис. 4.3 заданi у виглядi констант (модуль PROT). Наприклад, бiт P пpедставлений константою present = $80. Тодi байт доступу для кожного сегмента визначається як сума констант. Для сегмента коду байт доступу буде дорiвнювати: acc_code: = present OR nosys OR exe OR read, тобто вiн знаходиться в пам'ятi (P = 1), не є системним (S = 1), його можна виконувати (E = 1) i його можна читати (R = 1).

Формування дескpиптоpiв таблицi GDT здiйснюється за допомогою процедури модуля PROT init_gdt (i:byte; limit,base:longint; acces,d; g:byte), яка заносить значення параметрiв у вiдповiднi поля дескриптора.

Параметри процедури init_gdt мають такi значення:

i - номер дескриптора сегмента в GDT;

limit - гpаниця сегмента;

base - базова адреса сегмента;

acces - байт доступу;

byte_6h – значення старшої частини байта 6 дескриптора сегмента (в тому числі бiти  G і D).

Наприклад, в програмi P_MODE для формування дескpиптоpiв сегментiв коду (1), стека (4) i даних (3), що мають таке ж розташування в пам'ятi й тi ж розмiри, що i в реальному режимi, а також сегмента видеопам'ятi розмiром в одну сторiнку екрана (5) i другого сегмента даних (6), що пpедставляє розширену пам'ять i розташованого в пам'ятi починаючи вiд 1 Мбайта з гpаницей 4 Гбайти - 1 використовуються виклики процедури init_gdt з такими параметрами:

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

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

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

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

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

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

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

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

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

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

                                                  { Дескриптор сегмента розширеної пам'ятi (біт G=1): }

init_gdt(6,$fffff,1024*1024,acc_data,$80);

Лiнiйнi адреси сегментiв визначаються за допомогою описаної в модулi PROT функцiї lin_adr (seg, off: word): longint, параметрами якої є значення сегментного регiстра - seg i змiщення даних або команди вiдносно початку сегмента - off (для сегментiв значення off дорiвнює нулю).

Сама таблиця GDT задана у виглядi масиву її дескрипторiв: gdt:array[0..12] of t_gdt;

4.4. Завдання адреси i розмiру GDT

Пiсля формування дескpиптоpiв GDT необхiдно вказати мiкропроцесору мiсцеположення цiєї таблицi в пам'ятi та її розмiр.