Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Orgevm_Ekzamen.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
998.59 Кб
Скачать

Формат дескриптора.

3.15 Формат дескриптора.

Все создаваемые в системе дескрипторы можно разделить на системные и не системные. К системным относятся шлюзы, дескрипторы TSS и дескрипторы LDT. К не системным относятся дескрипторы сегментов кода, данных и стеков. Как системные, так и не системные дескрипторы занимают в памяти 8-мь байт и имеют примерно одинаковый формат (см. рис. 62).

Поле BASE задает 32-х разрядный начальный адрес сегмента.

Поле LIMIT задает размер сегмента. Этот размер может измеряться в байтах или страницах. Если размер сегмента задается в байтах размер сегмента может меняться от 1-го байта до 1-го Мбайта. Если размер задается в страницах он может меняться от 4-х Кбайт до 4-х Гбайт (от одной страницы до 220 страниц). Если размер сегмента стека задается в байтах, то этот размер лежит в более ограниченных пределах: от 1-го байта до 64-х Кбайт. Размеры сегментов TSS и таблиц LDT задаются только в байтах.

В каких единицах измеряется размер сегмента задает бит гранулярности G (granularity). Если G = 0 размер измеряется в байтах, при G = 1 -в страницах.

7 0

0h

Limit 7-0

1h

Limit 15-8

2h

Base 7-0

3h

Base 15-8

4h

Base 23-16

5h

P

DPL

S

TYPE

6h

G

D

0

U

Limit 19-16

7h

Base 31-24

Рис. 62

Бит P (present)- бит «присутствия». Если Р = 1 сегмент присутствует в ОП, а при Р = 0 - отсутствует, то есть находится на диске. При Р = 0 поля BASE и LIMIT не имеют вышеописанного смысла.

Бит U (user)- бит «пользователя». МП с этим битом не работает и системный программист может его использовать для набора статистических сведений о сегментах.

Бит D (default operation size)- бит «размерности». Это более сложный для описания бит. Возьмем для примера три команды: mov al , bl ; mov ax , bx и mov eax , ebx. Первая из этих трех команд имеет код операции ( КОП ) 88h, а вот у двух последующих команд КОП одинаковый, он равен 89h. То есть по коду операции возможно отличить «восьмиразрядные» команды от «не восьмиразрядных», а вот «шестнадцатиразрядные» команды от «тридцатидвухразрядных» по КОП отличить невозможно ( разумеется речь здесь идет об «аналогичных» командах). Для того чтобы МП мог отличить эти команды друг от друга перед одной из них транслятор поставит «префикс размера операнда» (66h). Перед какой из двух этих команд транслятор поставит префикс зависит от того как пользователь описал свою программу. У него для этого есть ассемблерные директивы use16 и use32. А вот МП проинтерпретирует эти команды в зависимости от бита D, который он возьмет в теневой части регистра cs. При D = 0 МП интерпретирует код 89h как команду mov ax , bx, а код 66h 89h - как команду mov eax , ebx. При D = 1 интерпретация таких кодов будет прямо противоположной. Кроме префикса размера операнда есть еще «префикс размера адреса» (67h). Его тоже ставит транслятор, например перед одной из двух команд: mov al ,[bx+2] и mov al , [ebx+2]. Интерпретация таких команд процессором аналогичным образом зависит от значения бита D в регистре cs. Отметим что перед командой могут стоять оба префикса одновременно. Эта несколько запутанная ситуация с префиксами и битом D связана с желанием уменьшить расход памяти и повысить быстродействие МП. Если было бы однозначно задано что префиксы, допустим, ставятся перед всеми «тридцатидвухразрядными» командами, а все «шестнадцатиразрядные» команды идут без префиксов казалось было бы проще. Однако если большинство команд программы «тридцатидвухразрядные», такая программа будет в этом случае (за счет префиксов !) занимать значительно больше памяти и медленнее выполняться. Вот бит D и предоставляет нам возможность как бы сообщать МП каких команд в нашей программе будет меньше 16-ти или 32-х разрядных. Перед теми которых меньше и будут стоять префиксы. Как уже говорилось в основном для интерпретации префиксов привлекается бит D из регистра cs. Биты D в регистрах ds, es, fs и gs по-видимому ни на что не влияют. Бит D в регистре ss определяет размер указателя стека ( D = 0 - sp, D = 1 - esp). В дескрипторах, копируемых в сегментный регистр стека ss биты D и G должны быть согласованы (равны между собой), кроме того бит D в подобных дескрипторах принято называть битом В (big – «бит большого сегмента»). Отметим также, что в дескрипторах «системных» сегментов биты D и G смысла не имеют.

Бит S (system)- бит «системного сегмента». При S = 0 дескриптор описывает системный сегмент. В зависимости от значения бита S процессор интерпретирует поле TYPE. При S = 1 (не системный сегмент) поле TYPE может иметь один из двух форматов.

Первый формат приведен на рис. 63

1

C

R

A

Рис. 63

Здесь 1-ца в старшем разряде поля TYPE означает что это сегмент кода. Бит А (accessed)-бит обращения. МП устанавливает этот бит при обращении к сегменту. Сбрасывать этот бит процессор сам не умеет, это делает системный программист. Бит R (read enable)- бит разрешения считывания. При R = 0 запрещается считывание информации из этого сегмента ( программу можно выполнять, но нельзя копировать). И наконец бит C (conforming)- бит «согласованного» сегмента. Понятие согласованного сегмента кода было введено раньше ( см. раздел 3.2).

Второй формат поля TYPE при S = 1 приведен на рис. 64.

0

E

R

A

Рис. 64

Здесь 0-ль в старшем разряде говорит о том что это сегмент данных. Бит A - бит обращения, такой же как и для сегментов кода. Бит W (write enable)- бит разрешения записи. При W = 0 сегмент запрещен для записи. Бит Е (expansion direction – «направление расширения») – грубо говоря, позволяет различать сегменты данных и сегменты стека (Е = 0 - это сегмент данных). Вернее, бит Е влияет на то как МП интерпретирует поле LIMIT. Продемонстрируем это с помощью рис. 65.

Рис. 65

Как видно из рисунка при Е = 0 МП считает что сегмент располагается в границах base - base+limit и следовательно если Аэф>base+limit мы выходим за заданные границы сегмента. При Е = 1 сегмент для МП располагается в границах base+limit - 64K (4Г) и выход за границы сегмента будет при Аэф<base+limit. Связано такое положение с тем, что если нам не хватает заданного размера сегмента, то сегменты данных удобней расширять в сторону старших адресов ОП (вверх), а сегменты стека, поскольку стек растет в сторону младших адресов, - вниз. Отметим что в сегментный регистр стека ss можно загружать дескрипторы сегментов и с Е = 0, и с Е = 1. Но при этом сегмент стека должен быть в любом случае разрешен для записи (W=1) и биты G и D должны быть согласованны. Например, мы хотим организовать стек в области ОП, от второго до третьего Мбайта. Можно пойти двумя путями:

  • Задаем Е = 0, G = D = 1, base задаем 2Мбайта, limit – 1Мбайт и указатель стека (esp) устанавливаем на 1Мбайт.

  • Задаем Е = 1, G = D = 1, base задаем равным нулю (можно и не нулю, но обязательно меньше или равно 2Мбайта), limit - 2Мбайта (конечно, если base взяли равным нулю) и esp указывает на 3Мбайта (опять таки если base взяли равным нулю. При этом esp «обрезает» сегмент со стороны старших адресов ОП.

В заключение этого раздела приведем форматы поля TYPE для системных сегментов (S=0):

  • 0000 -запрещенная комбинация;

  • 0001 -свободный TSS МП 286;

  • 0010 -таблица LDT;

  • 0011 -занятый TSS МП 286;

  • 0100 -шлюз вызова МП 286;

  • 0101 -шлюз задачи (одинаков для МП 286 и для 32 разрядных процессоров);

  • 0110 -шлюз прерывания МП 286;

  • 0111 -шлюз ловушки МП 286;

  • 1000 -запрещенная комбинация;

  • 1001 -свободный TSS 32 разрядного процессора;

  • 1010 -зарезервировано фирмой;

  • 1011 -занятый TSS 32 разрядного процессора;

  • 1100 -шлюз вызова 32 разрядного процессора;

  • 1101 -зарезервировано фирмой;

  • 1110 -шлюз прерываний 32 разрядного процессора;

  • 1111 -шлюз ловушки 32 разрядного процессора.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]