речь идет о содержимом регистра, то его название берут в круглые скобки. Мы также будем придерживаться этого обозначения.

6. Оператор переопределения типа ptr применяется для переопределения или уточнения типа метки или переменной, определяемых выражением (рис. 13).

Тип может принимать одно из следующих значений: byte, word, dword, qword, tbyte, near, far.

Рис. 13. Синтаксис оператора переопределения типа

7. Оператор переопределения сегмента «:» (двоеточие) заставляет вычислять физический адрес относительно конкретно задаваемой сегментной составляющей: «имя сегментного регистра», «имя сегмента» из соответствующей директивы SEGMENT или «имя группы» (рис. 14). При обсуждении сегментации мы говорили о том, что микропроцессор на аппаратном уровне поддерживает три типа сегментов – кода, стека и данных. В чем заключается такая аппаратная поддержка? К примеру, для выборки на выполнение очередной команды микропроцессор должен обязательно посмотреть содержимое сегментного регистра cs и только его. А в этом регистре, как мы знаем, содержится (пока еще не сдвинутый) физический адрес начала сегмента команд. Для получения адреса конкретной команды микропроцессору остается умножить содержимое cs на 16 (что означает сдвиг на четыре разряда) и сложить полученное 20- битное значение с 16-битным содержимым регистра ip. Примерно то же самое происходит и тогда, когда микропроцессор обрабатывает операнды в машинной команде. Если он видит, что операнд – это адрес (эффективный адрес, который является только частью физического адреса), то он знает, в каком сегменте его искать, – по умолчанию это сегмент, адрес начала которого записан в сегментном регистре ds.

А что же с сегментом стека? В контексте нашего рассмотрения нас интересуют регистры sp и Ър. Если микропроцессор видит в качестве операнда (или его части, если операнд – выражение) один из этих регистров, то по умолчанию он формирует физический адрес операнда, используя в качестве его сегментной составляющей содержимое регистра ss. Это набор микропрограмм в блоке микропрограммного управления, каждая из которых выполняет одну из команд в системе машинных команд микропроцессора. Каждая микропрограмма работает по своему алгоритму. Изменить его, конечно, нельзя, но можно чуть-чуть подкорректировать. Делается это с помощью необязательного поля префикса машинной команды. Если мы согласны с тем, как работает команда, то это поле отсутствует. Если же мы хотим внести поправку (если, конечно, она допустима для конкретной команды) в алгоритм работы команды, то необходимо сформировать соответствующий префикс.

Префикс представляет собой однобайтовую величину, численное значение которой определяет ее назначение. Микропроцессор распознает по указанному значению, что этот байт является префиксом, и дальнейшая работа микропрограммы выполняется с учетом поступившего указания на корректировку ее работы. Сейчас нас интересует один из них – префикс замены (переопределения) сегмента. Его назначение состоит в том, чтобы указать микропроцессору (а по сути, микропрограмме) на то, что мы не хотим использовать сегмент по умолчанию. Возможности для подобного переопределения, конечно, ограничены. Сегмент команд переопределить нельзя, адрес очередной исполняемой команды однозначно определяется парой cs: ip. А вот сегменты стека и данных – можно. Для этого и предназначен оператор «:». Транслятор ассемблера, обрабатывая этот оператор, формирует соответствующий однобайтовый префикс замены сегмента.

Рис. 14. Синтаксис оператора переопределения сегмента

8. Оператор именования типа структуры «.»(точка) также заставляет транслятор производить определенные вычисления, если он встречается в выражении.

9. Оператор получения сегментной составляющей адреса выражения seg возвращает физический адрес сегмента для выражения (рис. 15), в качестве которого могут выступать метка, переменная, имя сегмента, имя группы или некоторое символическое имя.

Рис. 15. Синтаксис оператора получения сегментной составляющей

10. Оператор получения смещения выражения offset позволяет получить значение смещения выражения (рис. 16) в байтах относительно начала того сегмента, в котором выражение определено.

Рис. 16. Синтаксис оператора получения смещения

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

Таблица 4. Операторы и их приоритет

3. Директивы сегментации

В ходе предыдущего обсуждения мы выяснили все основные правила записи команд и операндов в программе на ассемблере. Открытым остался вопрос о том, как правильно оформить последовательность команд, чтобы транслятор мог их обработать, а микропроцессор – выполнить.

При рассмотрении архитектуры микропроцессора мы узнали, что он имеет шесть сегментных регистров, посредством которых может одновременно работать:

1) с одним сегментом кода;

2) с одним сегментом стека;

3) с одним сегментом данных;

4) с тремя дополнительными сегментами данных.

Еще раз вспомним, что физически сегмент представляет собой область памяти, занятую командами и (или) данными, адреса которых вычисляются относительно значения в соответствующем сегментном регистре.

Синтаксическое описание сегмента на ассемблере представляет собой конструкцию, изображенную на рисунке 17:

Рис. 17. Синтаксис описания сегмента

Важно отметить, что функциональное назначение сегмента несколько шире, чем простое разбиение программы на блоки кода, данных и стека. Сегментация является частью более общего механизма, связанного с концепцией модульного программирования. Она предполагает унификацию оформления объектных модулей, создаваемых компилятором, в том числе с разных языков программирования. Это позволяет объединять программы, написанные на разных языках. Именно для реализации различных вариантов такого объединения и предназначены операнды в директиве SEGMENT.

Рассмотрим их подробнее.

1. Атрибут выравнивания сегмента (тип выравнивания) сообщает компоновщику о том, что нужно обеспечить размещение начала сегмента на заданной границе. Это важно, поскольку при правильном выравнивании доступ к данным в процессорах i80x86 выполняется быстрее. Допустимые значения этого атрибута следующие:

1) BYTE – выравнивание не выполняется. Сегмент может начинаться с любого адреса памяти;

2) WORD – сегмент начинается по адресу, кратному двум, т. е. последний (младший) значащий бит физического адреса равен 0 (выравнивание на границу слова);

3) DWORD – сегмент начинается по адресу, кратному четырем, т. е. два последних (младших) значащих бита равны 0 (выравнивание на границу двойного слова);

4) PARA – сегмент начинается по адресу, кратному 16, т. е. последняя шестнадцатеричная цифра адреса должна быть Oh (выравнивание на границу параграфа);

5) PAGE – сегмент начинается по адресу, кратному 256, т. е. две последние шестнадцатеричные цифры должны быть 00h (выравнивание на границу 256-байтной страницы);

6) MEMPAGE – сегмент начинается по адресу, кратному 4 Кбайт, т. е. три последние шестнадцатеричные цифры должны быть OOOh (адрес следующей 4-Кбайтной страницы памяти). По умолчанию тип выравнивания имеет значение PARA.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату