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

Unknown Author

Рассмотрим еще один пример на использование директив IF и IFE, в котором средства условного ассемблирования используются не самостоятельно, как в предыдущем примере, а для описания макросов, что является основным случаем применения этих средств.

Опишем в виде макроса SHIFT X,N операцию сдвига X на N разрядов вправо при условии, что параметр X - это имя какой-то переменной, а N - явно заданное положительное число, и при условии, что макрорасширение этого макроса должно содержать минимально возможное число команд.

Последнее условие означает, что по макрокоманде SHIFT X,N при N=1 должно формироваться макрорасширение из одной команды (SHR Х,1), а при N>1 - из двух команд (MOV CL,N и SHR X,CL). Поскольку здесь в зависимости от некоторого условия (величины N) в окончательный текст программы (в макрорасширение) должны попадать разные фрагменты, то ясно, что при описании макроса следует воспользоваться средствами условного ассемблирования. Сделать это можно, например, так:

SHIFT MACRO X,N

IFE N-l    ;;N-1»0? (N*1?)

SHR X,1

ELSE    ;;N>1

MOV CL,N

SHR X,CL

END IF

ENDM

Ниже для примера показано, как осуществляется макроподстановка для макрокоманды SHIFT А,5:

Х-»А, N->5 IFE 5-1    5-1=0?    MOV CL, 5

SHIFT А, 5    ^ SHR А, 1    ^ SHR A,CL

ELSE    нет

MOV CL,5 SHR A,CL END IF

11.4.2. Операторы отношения. Логические операторы

В общем случае константное выражение, указываемое в директивах IF и IFE, может быть любым, но по смыслу оно, конечно, должно быть логическим выражением. До сих пор мы рассматривали только арифметические (числовые) выражения ЯА, а теперь рассмотрим, как записываются логические выражения. Они считаются частным случаем константных выражений "вообще”, поэтому, хотя в основном используются в конструкциях макроязыка, принадлежат все же "чистому" Я А.

Прежде всего отметим, что в ЯА "ложью" считается число 0, а "истиной" считается число -1 (OFFFFh).

В ЯА имеется шесть операторов отношения:

Названия этих операторов расшифровываются следующим образом: EQ (equal) -равно, NE (not equal) - не равно, LT (less than) - меньше, LE (less or equal) -меньше или равно, GT (greater than) - больше, GE (greater or equal) - больше или равно. Оба операнда должны быть либо константными выражениями, либо адресными выражениями, значениями которых обязаны быть адреса из одного и того же сегмента памяти. Если проверяемое отношение выполняется, то значением оператора является "истина", не выполняется - "ложь". Например, если константа N имеет значение 5, тогда:

N+l LT 5 -> О (ложь)

N-l LT 5 -> -1 (истина)

Следует, однако, отметить, что действия этих операторов слегка "заумны". Операторы EQ и NE трактуют свои операнды как 16-битовые знаковые числа в дополнительном коде, поэтому выражение -2 EQ OFFFEh оказывается истинным. Остальные же операторы отношения правильно учитывают знаки своих операндов (например, отношение -1 LT OFFFEh истинно), кроме одного случая: если сравниваемые операнды равны как 16-битовые знаковые числа в дополнительном коде, то эти операторы считают их равными (например, отношение -1 LE OFFFFh считается ложным). Учитывая подобные "фокусы", лучше не использовать отрицательные числа в этих операторах.