Справочник по языку Ассемблера IBM PC

       

Псевдооператоры equ и =


К простейшим макросредствам языка ассемблера можно отнести псевдооператоры equ и "=" (равно).
Их мы уже неоднократно использовали при написании программ.
Эти псевдооператоры предназначены для присвоения некоторому выражению символического имени или идентификатора. Впоследствии, когда в ходе трансляции этот идентификатор встретится в теле программы, макроассемблер подставит вместо него соответствующее выражение.
В качестве выражения могут быть использованы константы, имена меток, символические имена и строки в апострофах. После присвоения этим конструкциям символического имени его можно использовать везде, где требуется размещение данной конструкции.

Синтаксис псевдооператора equ:

имя_идентификатора equ строка или числовое_выражение

Синтаксис псевдооператора “=”:

имя_идентификатора = числовое_выражение

Несмотря на внешнее и функциональное сходство псевдооператоры equ и “=” отличаются следующим:



  • из синтаксического описания видно, что с помощью equ

    идентификатору можно ставить в соответствие как числовые выражения, так и текстовые строки, а псевдооператор “=” может использоваться только с числовыми выражениями;

  • идентификаторы, определенные с помощью “=”, можно переопределять в исходном тексте программы, а определенные с использованием equ — нельзя.

Ассемблер всегда пытается вычислить значение строки, воспринимая ее как выражение. Для того чтобы строка воспринималась именно как текстовая, необходимо заключить ее в угловые скобки: <строка>.
Кстати сказать, угловые скобки являются оператором ассемблера, с помощью которого транслятору сообщается, что заключенная в них строка должна трактоваться как текст, даже если в нее входят служебные слова ассемблера или операторы. Хотя в режиме Ideal это не обязательно, так как строка для equ в нем всегда трактуется как текстовая.

Псевдооператор equ удобно использовать для настройки программы на конкретные условия выполнения, замены сложных в обозначении объектов, многократно используемых в программе, более простыми именами и т. п.
К примеру:

masm model small stack 256 mas_size equ 10 ;размерность массива akk equ ax ;переименовать регистр mas_elem equ mas[bx][si] ;адресовать элемент массива .data ;описание массива из 10 байт: mas db mas_size dup (0) .code mov akk,@data ;фактически mov ax,@data mov ds,akk ;фактически mov ds,ax ... mov al,mas_elem ;фактически — mov al,mas[bx][si]

<
Псевдооператор “=” удобно использовать для определения простых абсолютных (то есть не зависящих от места загрузки программы в память) математических выражений.
Главное условие то, чтобы транслятор мог вычислить эти выражения во время трансляции.
К примеру:
.data adr1 db 5 dup (0) adr2 dw 0 len = 43 len = len+1 ;можно и так, через предыдущее определение len = adr2-adr1

Как видно из примера, в правой части псевдооператора “=” можно использовать метки и ссылки на адреса — главное, чтобы в итоге получилось абсолютное выражение.

Компилятор TASM, начиная с версии 3.00, содержит директивы, значительно расширяющие его возможности по работе с текстовыми макросами. Эти директивы аналогичны некоторым функциям обработки строк в языках высокого уровня. Под строками здесь понимается текст, описанный с помощью псевдооператора equ.

Набор этих директив следующий:


  • директива слияния строк catstr:
    идентификатор catstr строка_1,строка_2,... — значением этого макроса будет новая строка, состоящая из сцепленной слева направо последовательности строк строка_1,строка_2,...

    В качестве сцепляемых строк могут быть указаны имена ранее определенных макросов.
    К примеру:
    pre equ Привет, name equ < Юля>

    privet catstr pre,name ;privet= “Привет, Юля”



  • директива выделения подстроки в строке substr:
    идентификатор substr строка,номер_позиции,размер — значением данного макроса будет часть заданной строки, начинающаяся с позиции с номером номер_позиции и длиной, указанной в размер.
    Если требуется только остаток строки, начиная с некоторой позиции, то достаточно указать только номер_позиции без указания размера.
    К примеру:
    ;продолжение предыдущего фрагмента: privet catstr pre,name ;privet= “Привет, Юля” name substr privet,7,3 ;name=“Юля”



  • директива определения вхождения одной строки в другую instr:
    идентификатор instr номер_нач_позиции,строка_1,строка_2 — после обработки данного макроса транслятором идентификатору

    будет присвоено числовое значение, соответствующее номеру (первой) позиции, с которой совпадают строка_1 и строка_2.
    Если такого совпадения нет, то идентификатор получит значение 0;
  • директива определения длины строки в текстовом макросе sizestr:
    идентификатор sizestr строка — в результате обработки данного макроса значение идентификатор устанавливается равным длине строки.
    ;как продолжение предыдущего фрагмента: privet catstr pre,name ;privet= “Привет, Юля” len sizestr privet ;len=10



  • Эти директивы очень удобно использовать при разработке макрокоманд, которые являются следующим макросредством, предоставляемым компилятором ассемблера.




    Содержание раздела