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

14. Записи даних. Застосування записів даних.

Записи, как и структуры, представляют собой шаблоны, накладываемые на реальные данные с целью введения удобных мнемонических обозначений отдельных элементов данных. В отличие от структур, дающих имена байтам, словам, двойным словам или целым массивам, в записях определяются строки битов внутри байтов, слов или двойных слов. Эти данные удобно специфицировать с помощью записи filedate, определяемой в программе следующим образом:

fdate record year:7, month: 4, day:5

Ключевое слово record говорит о том, что имя fdate относится к записи, а мнемонические обозначения year, month и day являются произвольными именами отдельных битовых полей описываемого слона.

Включение в программу описания шаблона битовых полей позволяет отказаться от утомительного и чреватого ошибками определения "вручную" содержимого полного данного по задаваемым значениям его отдельных составляющих. Для приведенной выше записи объявления конкретных переменных будут выглядеть следующим образом:

filel fdate <5,6,7> ;7 июня 1985г.

file2 fdate <18,12,30> ;30 декабря 1998г.

file3 fdate <> ;"Пустая" (пока) переменная

Переменная filel будет определена, как число 0AC7h, file2 - как число 259Eh, а fileЗ - как число 0000h. При необходимости программного заполнения переменной типа fdate можно пользоваться именами ее составляющих, которые трактуются ассемблером, как индексы соответствующих битовых полей, отсчитываемые от младшего конца слова. Для приведенного примера day=0, month=5, a year=9. Однако в системе команд МП 86 практически нет средств работы с битовыми полями. Поэтому программное заполнение придется осуществлять с помощью команд сдвигов и логического сложения:

mov flle3,30 ;Помещаем день

mov AX,12 ;Месяц пока в АХ

mov CL,month ;Будем сдвигать на month бит

shl AX,CL ; Сдвинули месяц в АХ на 5 бит

or file3,AX ;Добавили биты месяца в file3

mov AX, 18 ;Год пока в АХ

mov CL,month ;Будем сдвигать на year бит

shl AX,CL ;Сдвинули год в АХ на 9 бит

or file3,AX ;Добавили биты года в file3

В итоге в переменной file3 окажется тот же код 259Eh, что и в переменной file2.

15. Доступ до примірників записів даних. Див. Пункт 14.

16. Порядок виконання команд після повернення з обробки відмови.

Якщо в програмі передбачена обробка виключень, таку ситуацію можна виявити і як те виправити. Таким чином, в захищеному режимі програма не може вийти за межі оголошених нею сегментів, а також не може виконати дії, заборонені атрибутами сегменту. Так, якщо сегмент оголошений виконуваним (код атрибуту 1 981т), то дані з цього сегменту не можна читати або модифікувати; якщо атрибут сегменту рівний 92h, то в такому сегменті не може бути виконуваних команд, на зате дані можна як читати, так і модифікувати. Вказавши для якогось сегменту код атрибуту 90h, ми отримаємо сегмент із забороною запису. При спробі запису в цей сегмент процесор сформує виключення загального захисту.

Як вже наголошувалося, дескриптори сегментів зберігаються в процесі виконання програми в тіньових регістрах (див. мал. 4.11), які завантажуються автоматично при записі в сегментний регістр селектора.

При роботі в реальному режимі деякі поля тіньових регістрів мають бути заповнені цілком певним чином. Зокрема, поле межі будь-якого сегменту повинне містити число Ffffh, а біт дробу скинутий. Слід підкреслити, що межі всіх сегментів мають бути точно рівні Ffffh; будь-яке інше число, наприклад, Fffeh, "не влаштує" реальний режим.

Якщо ми просто перейдемо в реальний режим скиданням бита 0 в регістрі Cr0, то в тіньових регістрах залишаться дескриптори захищеного режиму і при першому ж зверненні до будь-якого сегменту програми виникне виключення загального захисту, оскільки жоден з наших сегментів не має межі, рівною Ffffh. Оскільки ми не обробляємо виключення, відбудеться або скидання процесора і перезавантаження комп'ютера, або зависання. Таким чином, перед переходом в реальний режим необхідно виправити дескриптори всіх наших сегментів: команд, даних, стека і відеобуфера До сегментних регістрів FS і GS ми не зверталися, і про них можна не піклуватися.

Тіньові регістри, куди, власне, треба записати значення межі, нам недоступні. Для з модифікації доведеться удатися до обхідного маневру: записати в поля меж всіх чотирьох дескрипторів значення Ffffh, а потім повторно завантажити селектори в сегментні регістри, що приведе до перезапису вмісту тіньових регістрів. З сегментним регістром CS так поступити не можна, тому його завантаження доведеться виконати, як і раніше, за допомогою штучної сформованої команди дальнього переходу.

Набудувавши сегментні регістри, що все використалися в програмі, можна скинути біт 0 в Cr0. Після переходу в реальний режим нам доведеться ще раз виконати команду дальнього переходу, щоб очистити чергу команд в блоці передвибірки і завантажити в регістр CS замість селектора, що зберігається там, звичайну сегментну адресу регістра команд.

Тепер процесор знову працює в реальному режимі, причому, хоча в сегментних регістрах DS, ES і SS залишилися незаконні для реального режиму селектори, програма якийсь час виконуватиметься правильно, оскільки в тіньових регістрах знаходяться правильні лінійні адреси (що залишилися від захищеного режиму) і законні для реального режиму межі (завантажені туди нами). Якщо, проте, в програмі зустрінуться команди збереження і відновлення вмісту сегментних регістрів, наприклад

push DS

...

pop DS

виконання програми буде порушено, оскільки команда pop DS завантажить в DS не сегментну адресу реального режиму, а селектор, тобто число 8 в нашому випадку. Це число розглядатиметься процесором, як сегментна адреса, і подальші звернення до полів даних приведуть до адресації фізичної пам'яті починаючи з абсолютної адреси 80h, що, звичайно, позбавлено сенсу. Навіть якщо в нашій програмі немає рядків збереження і відновлення сегментних регістрів, вони неминуче зустрінуться, як тільки відбудеться перехід в DOS по команді int 21h, оскільки диспетчер DOS зберігає, а потім відновлює всі регістри завдання, у тому числі і сегментні. Тому після переходу в реальний режим необхідно завантажити у використовувані далі сегментні регістри відповідні сегментні адреси, що і виконується в програмі для регістрів DS і SS. Треба також не забути вирішити заборонені нами раніше апаратні переривання (команда sti).

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