7.2. Оператор EQTYPE

Ещё один оператор — EQTYPE. Он определяет, одинаков ли тип идентификаторов.

Существующие типы:

отдельные строки символов, заключённые в кавычки (те, которые не являются частью численных выражений)

вещественные числа (с плавающей точкой)

любые численные выражения, например, 2+2 (любой неизвестный символ будет рассматриваться как метка, так что он будет считаться подобным выражением)

адреса — численные выражения в квадратных скобках (учитывая оператор размерности и префикс сегмента)

мнемоники инструкций

регистры

операторы размерности

операторы NEAR и FAR

операторы USE16 и USE32

пустые аргументы (пробелы, символы табуляции)

Пример макроса, который позволяет использовать переменную в памяти в качестве счётчика в инструкции SHL (например shl ax, [myvar]):

macro shl dest, count

{

 if count eqtype [0]  ;если count — ячейка памяти

  push cx

  mov cl, count

  shl dest, cl

  pop cx

 else             ;если count другого типа

  shl dest, count ;просто используем обычную shl

 end if

}

shl ax, 5

byte_variable db 5

shl ax, [byte_variable]

получится:

if 5 eqtype [0]

 push cx

 mov cl, 5

 shl ax, cl

 pop cx

else

 shl ax, 5

end if

byte_variable db 5

if [byte_variable] eqtype [0]

 push cx

 mov cl, [byte_variable]

 shl ax, cl

 pop cx

else

 shl ax, [byte_variable]

end if

в результате обработки условий конечный результат будет:

 shl ax, 5

byte_variable db 5

 push cx

 mov cl, [byte variable]

 shl ax, cl

 pop cx

Заметьте, что shl ax, byte [myvar] не будет работать с этим макросом, так как условие byte [variable] eqtype [0] не выполняется. Читаем дальше.

Когда мы сравниваем что-то посредством EQTYPE, то это что-то может быть не только единичным идентификатором, но и их комбинацией. В таком случае, результат eqtype истина, если не только типы, но и порядок идентификаторов совпадают. К примеру, if eax 4 eqtype ebx name — верно, так как name — это метка, и её тип — численное выражение.

Пример расширенной инструкции mov, которая позволяет перемещать данные между ячейками памяти:

macro mov dest,src

{

 if dest src eqtype [0] [0]

  push src

  pop dest

 else

  mov dest,src

 end if

}

mov [var1], 5

mov [var1], [var2]

преобразуется препроцессором в:

if [var1] 5 eqtype [0] [0] ;не верно

 push 5

 pop [var1]

else

 mov [var1],5

end if

if [var1] [var2] eqtype [0] [0] ;верно

 push [var2]

 pop [var1]

else

 mov [var1], [var2]

end if

и будет ассемблировано в:

 mov [var1], 5

 push [var2]

 pop [var1]

Хотя более удобно для восприятия реализовать макрос используя логический оператор И — &:

macro mov dest,src

{

 if (dest eqtype [0]) & (src eqtype [0])

  push src

  pop dest

 else

  mov dest, src

 end if

}

Пример с использованием EQTYPE с четырьмя аргументами приведён для демонстрации возможностей, обычно проще использовать в таких случаях &. Кстати, в качестве аргументов, возможно использовать некорректные выражения — достаточно, чтобы лексический анализатор распознал их тип. Но это не является документированным, так что не будем этот обсуждать.