Защищённый режим:

Глава 7. Глобальная дескрипторная таблица.

        Прежде, чем процессор перейдёт в защищённый режим, должна быть определена глобальная дескрипторная таблица GDT (Global Descriptor Table), так как все сегменты и прочие системные объекты должны быть описаны в дескрипторной таблице.
        Глобальная дескрипторная таблица GDT - это область памяти, в которой находятся дескрипторы. Процессору всё равно, где именно вы расположили эту таблицу, но в любом случает она будет находится в первом мегабайте адресного пространства, потому что только из режима реальных адресов можно перевести процессор в защищённый режим. Также подразумевается, что сама таблица GDT будет выравнена на границу 8 байт, так как дескрипторы, из которых она состоит, имеют 8-байтный размер. Такое выравнивание позволит процессору максимально быстро обращаться к дескрипторам, что, естественно, увеличивает производительность.
        Число дескрипторов, определённых в GDT, может быть любым, от 0 до 8192. Нулевой дескриптор, т.е. определённый в самом начале GDT, процессор не использует, обращение к такому дескриптору могло бы быть, когда поле Index селектора равно 0. Если всё же в программе встречается обращение к нулевому дескриптору, то процессор генерирует исключение и не позволит доступ к такому дескриптору. В связи с этим, везде в литературе рекомендуется использовать нулевой дескриптор как шаблон, на основе которого программа может создавать новые дескрипторы, но на практике их удобнее создавать иными способами, о которых мы ещё будем говорить.

        GDT используется процессором всё время, пока он находится в защищённом режиме. Параметры GDT хранятся в специальном 48-разрядном регистре GDTR:


Рисунок 7-1. Формат регистра GDTR.

        Формат регистра GDTR следующий:
биты:  
0..15: 16-разрядный предел GDT
15..47: 32-разрядный адрес начала GDT

        Адрес начала GDT - это тот адрес, по которому вы разместили GDT.
        Предел таблицы GDT - это максимальное смещение относительно её начала.

        Например, вы создаёте GDT, состоящую из 3-х дескрипторов - для сегментов кода, стека и данных. Общее число дескрипторов будет равно четырём, потому что первым по счёту будет идти нулевой дескриптор, а за ним уже остальные три:

Смещение от начала GDT Назначение дескриптора
0 Нулевой
8 Сегмент кода
16 Сегмент стека
24 Сегмент данных

        Размер GDT в данном случае будет равен 32 байтам, следовательно, предельное смещение в таблице будет равно 31 - это и есть предел GDT.

        Для загрузки значения в регистр GDTR используется команда LGDT. Операндом этой команды является 48-разрядное значение адреса в памяти, где размещается адрес и предел GDT. Вы также можете сохранить содержимое GDTR командой SGDT, указав в операнде адрес 48-разрядной переменной в памяти.

        Далее приводится пример подготовки параметров GDT и их загрузки в регистр GDTR.


Пример 1. Подготовка параметров GDT и их загрузка в регистр GDTR.

Алгоритм:

1. Вычисляем 32-разрядный адрес GDT
2. Вычисляем размер GDT
3. Сохраняем параметры GDT в 48-разрядную переменную
4. Загружаем значение в регистр GDTR

Код:

; 1. Вычисляем 32-разрядный адрес GDT

	xor	eax,eax	; EAX = 0; адрес будем вычислять в
				;  регистре EAX.
	mov	ax,ds		; Подразумевается, что GDT находится в
				;  текущем сегменте данных.
	shl	eax,4		; EAX = адрес начала сегмента DS

	xor	edx,edx	; EDX = 0.
	lea	dx,GDT		; EDX = DX = смещение начала GDT
				;  относительно DS.

	add	eax,edx	; EAX = полный физический адрес GDT
				;  в памяти.


; 2. Вычисляем размер GDT

	mov	cx,4		; CX = число дескрипторов +
				;  + нулевой дескриптор.
	shl	cx,3		; CX = CX * 8 - столько байт будут
				;  занимать в GDT эти дескрипторы.

	dec	cx		; Предел меньше размера на 1


; 3. Сохраняем параметры GDT в 48-разрядную переменную

	mov	GDT_address,eax
	mov	GDT_limit,cx


; 4. Загружаем значение в регистр GDTR

	lgdt	GDT_params

;--------------------------------------------------------------------------

GDT_params	label	fword
GDT_limit	dw	?
GDT_address	dd	?


GDT:
	dd	?	; 0-й дескриптор
	dd	?

	dd	?	; 1-й дескриптор (код)
	dd	?

	dd	?	; 2-й дескриптор (стек)
	dd	?

	dd	?	; 3-й дескриптор (данные)
	dd	?

        Остаётся добавить, что размер GDT желательно не менять в процессе выполнения программ в защищённом режиме. Если ваша программа будет динамически создавать новые дескрипторы, то размер GDT лучше всего заранее задать достаточно большим, например, 64 Кб (максимальный размер). Однако, следует учитывать, что при обращении процессора к несуществующим дескрипторам, его поведение непредсказуемо, хотя оно, скорее всего, закончится зависанием.

Следующая глава Оглавление Вопросы? Замечания? Пишите: sasm@narod.ru

  Copyright © Александр Семенко.
TopList

Hosted by uCoz