
- •Лабораторна робота n7
- •Зміст роботи.
- •Довідкові дані.
- •Суть захищеного режиму
- •Захист від взаємного впливу програм.
- •Елементи організації захищеного режиму
- •Елементи системи привілеїв
- •Переривання в захищеному режимі.
- •Етап 1. Переключення в захищений режим та повернення в режим реальних адрес.
- •Перевірка поточного режиму процесора
- •Підготовка системних структур даних для роботи в захищеному режимі
- •Переключення процесора в захищений режим
- •Виведення повідомлення на екран
- •Послідовність дій для переводу процесора в режим реальних адрес.
- •Переформувати дескриптори сегментів даних і стека згідно вимог:
- •Завантажити селектори обновлених дескрипторів
- •Переключення в режим реальних адрес, вихід в dos, (припускаємо, що логічний сегмент нашої програми - code)
- •Int 21h ; чекать введення з клавіатури
- •Int 10h ; переключить відеоконтролер
- •Етап 2. Підготовка системних структур даних для забезпечення функціонування механізму переривань
- •Формування процедур обробки переривань
- •Розміщення та формування дескриптора сегмента Int_code в gdt.
- •Формування таблиці векторів переривань (idt)
- •Формування та запис вказівника таблиці векторів переривань.
- •Відновлення стандартної таблиці переривань при переключенні в реальний режим
- •Завдання на лабораторну роботу
- •Ускладнені завдання.
- •Питання для перевірки.
Формування таблиці векторів переривань (idt)
В загальному випадку таблиця містить системні дескриптори (шлюзи) пасток, переривань та задач. В даній роботі вона містить лише шлюзи пасток. Шлюз пастки, як і інші дескриптори, має розмір 8 байт і містить наступні поля, в порядку їх розміщення в дескрипторі:
Молодші 2 байти зміщення процедури обробки переривань в відповідному сегменті кодів (в нашому випадку - в сегменті Int_code)
2 байти селектора сегмента (в нашому випадку offset deskr_Int_code)
Нульовий байт
Байт атрибутів (в нашому випадку це 10001111b)
Старші два байти зміщення процедури обробки переривань в відповідному сегменті кодів (в нашому випадку нульове значення, оскільки сегмент Int_code має розмір менше чим 64К)
Таким чином в нашому випадку всі шлюзи будуть відрізняться лише вмістом першого поля.
Таблицю IDT доцільно розміщувати в окремому сегменті:
IDT segment para public 'data' use16
Vector=0
Rept 256
Dw Vector * Proc_int_size; зміщення процедури
Dw offset deskr_Int_code; селектор дескриптора в GDT
Db 0; завжди 0
Db 10001111b ;байт атрибутів - шлюз пастки
Dw 0; всі процедури розміщуються в перших 64К
Vector=Vector+1
Endm
IDT ends
Формування та запис вказівника таблиці векторів переривань.
До програмно доступних регістрів процесора відноситься спеціальний регістр IDTR, який повинен містить фізичну адресу таблиці векторів переривань та її розмір. Завантаження цього регістру може виконуватись в реальному режимі за допомогою команди LIDT процесора, яка повинна адресувати 6-байтний вказівник
Визначимо вказівник для IDT (в логічному сегменті даних _DATA):
pidt pointdt <>
Формування вказівника і завантаження IDT (вважаємо, що регістр DS містить адресу сегменту _DATA, а Асемблер за допомогою директиви assume про це проінформований):
; формування IDT
xor eax,eax
mov ax,IDT
shl eax,4
mov pidt.adr,eax
mov pidt.lim,8*256
; завантаження IDT
lidt pidt
В результаті сформовано всі необхідні системні дані для запуску процедур обробки переривань по любому із 256 векторів. Обробка переривання полягає в виведенні на екран номера вектора та передачу управління на переключення в реальний режим.
Відновлення стандартної таблиці переривань при переключенні в реальний режим
Після повернення в режим реальних адрес перед тим, як дозволить переривання, необхідно в IDTR завантажити покажчик таблиці переривань реального режиму, наприклад
xor eax,eax
mov pidt.adr,eax
mov pidt.lim,3ffh
lidt pidt
РЕКОМЕНДАЦІЯ ПО НАЛАГОДЖЕННЮ ПРОГРАМ.
Після переключення в захищений режим не має можливості використати ні AFD ні TD. Крім того, в результаті помилок в формуванні системних даних захищеного режиму процесор напевно буде автоматично перезапускатись. Для визначення команди (групи команд), які призводять до аварії можна використовувати команду
Jmp $ ; передача управління на саму себе
В результаті програма “зациклиться” і аварії не буде. Якщо програма приводить до аварії, то “аварійні” команди виконуються раніше, ніж команда Jmp $ . Послідовно розміщуючи команду Jmp $ можна визначить команду, яка призводить до аварії та визначить помилку в програмі.
Інколи допомагає виведення на екран довільних повідомлень , або вмісту регістрів (наприклад за допомогою процедури SHOW із лабораторної роботи №6.