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

5. Початкове завантаження сегментних регістрів

Директива ASSUME повідомляє асемблеру про те, по яких регістрах він повинен сегментувати імена з яких сегментів, і "обіцяє", що в цих регістрах будуть перебувати початкові адреси цих сегментів. Однак завантаження цих адрес у регістри сама директива не здійснює. Зробити таке завантаження - обов'язок самої програми, із завантаження сегментних регістрів і повинно починатися виконання програми. Робиться це так.

Оскільки в ПК немає команди пересилання безпосереднього операнда в сегментний регістр (а ім'я, тобто початок, сегменту - це безпосередній операнд), то таке завантаження доводиться робити через якийсь другий, несегментний, регістр (наприклад, AX):

MOV AX,DT1 ;AX:=початок сегмента DT1

MOV DS,AX ;DS:=AX

Аналогічно завантажується й регістр ES.

Завантажувати регістр CS на початку програми не треба: він, як і лічильник команд IP, завантажується операційною системою перед тим, як починається виконання програми (інакше не можна було б почати її виконання). Що ж стосується регістра SS, використовуваного для роботи зі стеком, то він може бути завантажений так само, як і регістри DS й ES, однак в MASM передбачена можливість завантаження цього регістру ще до виконання програми

6. Посилання вперед

Зустрічаючи в символьній команді посилання назад - ім'я, що описане у тексті програми до цієї команди, асемблер уже має необхідну інформацію про ім'я й тому може правильно відтранслювати цю команду. Але якщо в команді зустрінеться посилання вперед, тобто ім'я, що не було описано до команди і яке, напевно, буде описано пізніше, то асемблер у більшості випадків не зможе правильно відтранслювати цю команду. Наприклад, не знаючи, у якому програмному сегменті буде описано це ім'я, асемблер не може визначити, по якому сегментному регістру треба сегментувати ім'я, і тому не може визначити, треба чи ні розміщати перед відповідною машинною командою префікс заміни сегменту а, якщо треба, то який саме.

У подібній ситуації асемблер діє в такий спосіб: якщо в команді зустрілося посилання вперед, то він робить деяке припущення щодо цього імені й уже на основі цього припущення формує машинну команду. Якщо потім (коли зустрінеться опис імені) виявиться, що дане припущення було невірним, тоді асемблер намагається виправити сформульовану ним раніше машинну команду. Однак це не завжди вдається: якщо правильна машинна команда повинна займати більше місця, ніж машинна команда, побудована на основі припущення (наприклад, перед командою треба насправді вставити префікс заміни сегмента), тоді асемблер фіксує помилку (як правило, це помилка номер 6: Phase error between passes.)

Яке ж припущення робить асемблер, зустрічаючи посилання вперед? У всіх командах, крім команд переходу, асемблер припускає, що ім'я буде описано в сегменті даних і тому сегментується по регістру DS. Це варто враховувати при складанні програми: якщо в команді зустрічається посилання вперед на ім'я, що описане в сегменті, на початок якого вказує сегментний регістр, відмінний від DS, то перед таким ім'ям автор програми повинен написати відповідний префікс. Приклад:

code segment

assume cs:code

x dw ?

beg: mov ax,x ;тут замість cs:x можна записати просто x

mov cs:y,ax ;тут обов'язково треба записати cs:y

y dw ?

code ends

Лекція 7

Тема: Операції з рядками