Реферат: DOS-extender для компилятора Borland C++
Рис. 2. Форматы поля доступа дескриптора.
Поле доступа дескриптора сегментов кода содержит битовое поле R, называемое битом разрешения чтения сегмента. Если этот бит установлен в 1, программа может считывать содержимое сегмента кода. В противном случае процессор может только выполнять этот код.
Биты P и A предназначены для организации виртуальной памяти. Их назначение будет описано в разделе, посвящённом виртуальной памяти. Сейчас отметим, что бит P называется битом присутствия сегмента в памяти. Для тех сегментов, которые находятся в физической памяти (мы будем иметь дело в основном с такими сегментами) этот бит должен быть установлен в 1.
Любая попытка программы обратиться к сегменту памяти, в дескрипторе которого бит P установлен в 0, приведёт к прерыванию.
Бит A называется битом обращения к сегменту и для всех наших программ должен быть установлен в 0.
Поле доступа дескриптора сегмента данных имеет битовые поля W и D. Поле W называется битом разрешения записи в сегмент. Если этот бит установлен в 1, наряду с чтением возможна и запись в данный сегмент. В противном случае при попытке чтения выполнение программы будет прервано.
Поле D задаёт направление расширения сегмента. Обычный сегмент данных расширяется в область старших адресов (расширение вверх). Если же в сегменте расположен стек, расширение происходит в обратном направлении - в область младших адресов (расширение вниз). Для сегментов, в которых организуются стеки, необходимо устанавливать поле D равным 1.
Рассмотрим, как таблица дескрипторов будет выглядеть на языке программирования C. (В дальнейшем где это только возможно будем применять язык С, а Ассемблер – только там, где это необходимо.):
typedef struct descriptor
{
wordlimit; // Предел (размер сегмента в байтах)
wordbase_lo; // Базовый адрес сегмента (младшее слово)
unsignedcharbase_hi; // Базовый адрес сегмента (старший байт)
unsignedchar type_dpl; // Поле доступа дескриптора
unsignedreserved; // Зарезервированные 16 бит
} descriptor;
Данная структура описана в файле tos.h.
Инициализацию экземпляра такой структуры можно произвести при помощи функции, подобной функции init_gdt_descriptor, описанной в файле tos.c:
void init_gdt_descriptor(descriptor *descr,
unsigned long base,
word limit,
unsigned char type)
{
// Младшее слово базового адреса
descr->base_lo = (word)base;
// Старший байт базового адреса
descr->base_hi = (unsigned char)(base >> 16);
// Поле доступа дескриптора