Читать «Assembler. Программирование на языке ассемблера IBM PC» онлайн - страница 32

Unknown Author

Если же в PTR указано адресное выражение, то оператор "говорит", что адрес, являющийся значением выражения, должен восприниматься ассемблером как адрес ячейки указанного типа (размера); например: WORD PTR А - адрес А обозначает слово (байты с адресами А и А+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 - переменная размером в слово:

2 DW 1234h    ;Z: 34h, Z+ls. 12b

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

MOV z,o

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

MOV BYTE PTR Z,0 ; Z: OOh, Z+l: 12h

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

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

MOV Z+l,15

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

MOV BYTE PTR (Z+l),15

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

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