Оператор указания типа (PTR)




А теперь рассмотрим ситуацию, когда по операндам команды MOV нельзя определить размер пересылаемой величины.

Забегая вперед, отметим, что если некоторый адрес А надо модифицировать, скажем, по регистру SI, то в ЯА это записывается так: A[SI]. Исполнительный адрес в этом случае вычисляется по формуле Aисп = A + [SI]. В частности, при А=0 запись имеет вид [SI] (0 не указывается) и задает исполнительный адрес, равный содержимому регистра SI: Аисп = [SI].

C учетом этого рассмотрим такую задачу. Пусть в регистре SI находится адрес некоторой ячейки памяти и требуется записать 0 в эту ячейку. Тогда, казалось такое обнуление можно сделать с помощью команды

MOV [SI], 0

Однако это не так. Дело в том, что по этой команде нельзя понять, какого размера ноль пересылается, поскольку второй операнд может обозначать ноль как размером в байт (00h), так и размером в слово (0000h), а что касается первого операнда, то адрес из регистра SI может быть адресом ячейки как размером в байт, так и размером в слово (напомним, что с одного и того же адреса могут начинаться ячейки разных размеров).

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

Для этого в ЯА введен оператор указания типа PTR (от pointer, указатель), который записывается следующим образом:

<тип> PTR <выражение>

где <тип> - это BYTE, WORD или DWORD (есть и другие варианты, но мы их пока не рассматриваем), а выражение может быть константным или адресным.

Если указано константное выражение, то оператор "говорит", что значение этого выражения (число) должно рассматриваться ассемблером как величина указанного типа (размера); например, BYTE PTR 0 - это ноль как байт, a WORD PTR 0 - это ноль как слово (запись BYTE PTR 300 ошибочна, т. к. число 300 не может быть байтом). Отметим, что в этом случае оператор PTR относится к константным выражениям.

Если же в PTR указано адресное выражение, то оператор "говорит", что адрес, являющийся значением выражения, должен восприниматься ассемблером как адрес ячейки указанного типа (размера); например: WORD PTR A - адрес А обозначает слово (байты с адресами А и А+1). В данном случае оператор PTR относится к адресным выражениям.

С использованием оператора PTR наша задача решается так: если мы имеем в виду обнуление байта по адресу из регистра SI, то для этого надо использовать команду

MOV BYTE PTR [SI],0 или MOV [SI], BYTE PTR 0

а если надо переслать нулевое слово, то команду

MOV WORD PTR [SI],0 ИЛИ MOV [SI], WORD PTR 0

Отметим, что обычно принято уточнять тип операнда-адреса, а не тип непосредственного операнда.

Оператор PTR полезен еще в одной ситуации - когда надо не уточнить тип операнда, а изменить его. Пусть, к примеру, Z - переменная размером в слово:

Z DW 1234h;Z: 34h, Z+l: 12h

и надо записать ноль не во все это слово, а только в его первый байт - в тот, где находится величина 34h. Так вот, сделать это командой

MOV Z,0

нельзя, т. к. по ней 0 запишется в оба байта. Почему? Имя Z описано в директиве DW и потому, как мы уже знаем, получает тип WORD: TYPE Z = WORD. Когда ассемблер определяет размер операнда команды, в качестве которого указано имя переменной, то он учитывает тип, полученный именем при описании. Поэтому в нашем случае ассемблер и считает, что пересылается нулевое слово. Обычно так и должно быть, но сейчас нас это не устраивает, нам сейчас нужно, чтобы ассемблер рассматривал Z как имя байта. Вот такое изменение типа имени и позволяет сделать оператор PTR:

MOV BYTE PTR Z,0; Z: 00h, Z+1: 12h

Здесь мы сказали ассемблеру, чтобы он игнорировал тот тип имени Z, который был приписан ему при описании, и считал, что имя Z обозначает байт. (Отметим, что такое изменение типа локально, оно действует только в данной команде.)

Аналогичная ситуация возникает, если мы хотим получить доступ ко второму байту переменной Z. Например, для записи 15 в этот байт нельзя использовать команду

MOV Z+1,15

т. к. считается, что адрес Z+1 обозначает слово. Это общее правило в ЯА: адрес вида <имя>+/-<целое> имеет тот же тип, что и <имя>. Поэтому число 15 запишется в два байта - с адресами Z+1 и Z+2. Если же мы хотим изменить только байт по адресу Z+1, тогда надо воспользоваться оператором PTR:

MOV BYTE PTR (Z+1),15

Здесь конструкция BYTE PTR (Z+1) "говорит", что Z+1 надо рассматривать как адрес байта, а не слова.

Отметим, что в ЯА оператор PTR по старшинству выполняется до оператора сложения, поэтому запись BYTE PTR Z+1 трактуется как (BYTE PTR Z)+l. Однако в данном конкретном случае старшинство операторов не играет никакой роли, т. к. обе записи - BYTE PTR (Z+1) и BYTE PTR Z+1 - эквивалентны по смыслу: в первом случае мы сначала увеличиваем адрес Z на 1 и только затем сообщаем, что Z+1 надо рассматривать как адрес байта, а во втором случае мы сначала сообщаем, что Z - это адрес байта, и лишь затем увеличиваем его на 1 при этом "байтовость" адреса сохраняется).

Итак, оператор PTR используется в следующих ситуациях: когда типы операндов команд неизвестны и потому надо указать явно тип одного из операндов, i когда нас не устраивает тип, приписанный имени при его описании, и потому мы должны указать нужный нам тип.

Команда XCHG

В машинных программах приходится довольно часто переставлять местами какие-то две величины, и хотя такую перестановку можно реализовать только с помощью команды MOV, в ПК введена специальная команда для этого:

перестановка (exchange): XCHG opl, op2

Эта команда меняет местами значения своих операндов (они должны быть либо байтами, либо словами): ор1 <=> ор2. Флаги при этом не меняются.

Пример:

Допустимые типы операндов команды XCHG:

Как видно, не допускается перестановка содержимого двух ячеек памяти. Если все-таки надо сделать такую перестановку, то это реализуется через какой-нибудь регистр. Например, поменять местами значения байтовых переменных X и Y можно так:



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: