Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 3000239.doc
Скачиваний:
23
Добавлен:
30.04.2022
Размер:
1.12 Mб
Скачать

2.4. Директивы эквивалентности и присваивания

Было рассмотрено, как в языке ассемблера описываются переменные. Теперь рассмотрим, как в этом языке описываются константы. Это делается с помощью директивы эквивалентности – директивы EQU (equal, равно), имеющей следующий синтаксис:

<имя> EQU <операнд>

Здесь обязательно должно быть указано имя, должен быть и операнд, причем только один.

Эта директива аналогична описанию константы в языке Паскаль:

const <имя> = <операнд>

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

STAR EQU '*'

то ассемблер будет рассматривать предложение

Т DB STAR

как предложение

T DB '*'

Другими словами, указать имя STAR и указать '*' – это одно и то же. Отметим, что директива EQU носит чисто информационный характер, по ней ассемблер ничего не записывает в машинную программу. Поэтому директиву EQU можно ставить в любое место программы - и между командами, и между описаниями переменных, и в других местах.

Теперь рассмотрим, каким может быть операнд директивы EQU и в каких случаях полезна эта директива.

Операнд - имя

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

A DW?

В EQU A

С DW В ; эквивалентно: С DW A

Имена-синонимы обычно используются для введения более удобных, наглядных обозна­чений. Например, само по себе имя регистра АХ ни о чем не говорит, но если мы исполь­зуем этот регистр для вычисления какой-то суммы, то его можно обозначить SUM:

SUM EQU AX

и далее использовать это более наглядное имя SUM.

Отметим, что имя, указанное в правой части директивы EQU, может быть описано в программе как до этой директивы, так и после нее.

Операнд – константное выражение

Примеры:

N EQU 100

К EQU 2*N-1

STAR EQU '*'

Если в правой части директивы EQU стоит константное выражение, тогда ука­занное слева имя принято назы­вать именем константы. Значением этой константы объявляется зна­чение выражения. Например, N - это кон­станта со значением 100, К – со значением 199, a STAR – со значением 2Ah (это код звездочки в системе ASCII). Все последующие вхожде­ния в текст программы имени константы ассемблер будет заменять на значение этой константы. Например, директива

X DB N DUP (?)

эквивалентна директиве

X DB 100 DUР (?)

Случаи, когда полезно применение констант, - такие же, как и в языках высокого уровня. Например, в качестве констант рекомендуется описывать размеры массивов, поскольку в таком случае легко настроить программу на работу с массивом другого размера – для этого достаточно внести изменение лишь в директиву EQU, описывающую константу.

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

Операнд – любой другой текст

Примеры:

S EQU 'Вы ошиблись'

LX EQU X+(N-1)

WP EQU WORD PTR

В данном случае считается, что указанное имя обозначает операнд в том виде, как он записан (операнд не вычисляется). Именно на этот текст и будет заменяться каждое вхождение данного имени в программу. Например, следующие предложения слева эквивалентны предложениям справа

ANS DB S, '!' ANS DB 'Вы ошиблись', '!'

NEG LX NEG X+(N-1)

INC WP [BX] INC WORD PTR [BX]

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

Следует отметить, что текст, указанный в правой части директивы EQU, должен быть сбалансирован по скобкам и ка­вычкам и не должен содержать вне скобок и кавычек символа ";". Кроме того, поскольку текст не вычисляется, то в нем можно использовать как имена, описанные до этой директивы EQU, так и имена, описанные после нее.

Теперь рассмотрим еще одну директиву языка ассемблера, похожую на директиву EQU, - директиву присваивания:

<имя> = <константное выражение>

Эта директива определяет константу с именем, указанным в левой части, и с числовым значением, равным значению выражения справа. Но в отличие от констант, определенных по директиве EQU, данная константа может менять свое значение, обозначая в разных час­тях текста программы разные числа. Например:

K=10

A DW К ;эквивалентно: A DW 10

К=К+4

В DB К ;эквивалентно: В DB 14

Подобного рода константы можно использовать, например, ради «экономии имен»: если в разных частях текста программы используются разные константы и области использова­ния этих констант не пересекаются, тогда, чтобы не придумывать новые имена, этим константам можно дать одно и то же имя (другими словами, поменять значение константы с таким именем). Однако главное применение таких констант – в макросредствах.

Если с помощью директивы EQU можно определить имя, обозначающее не только число, но и другие конструкции, то по директиве присваивания можно определить только числовую константу. Кроме того, если имя указано в левой части директивы EQU, то оно не может появляться в левой части других директив (его нельзя переопределять). А вот имя, появившееся в левой части директивы присваивания, может снова появиться в начале другой такой директивы (но только такой!). Поэтому ошибочными являются все следующие три фрагмента программы:

К EQU 1 К EQU 1 К=1

К EQU 2 К=2 К EQU 2

Появление в языке констант, которые могут менять свои значения, вносит некоторую неопределенность. Рассмотрим, к примеру, фрагмент слева:

K=1 К=1

N EQU К N EQU К+10

A DW N ;А=1 С DW N ; С=11

К=2 К=2

В DW N ;В=2 D DW N ;D=11

Какие начальные значения получат переменные А и В? Относительно значения переменной А сомнений нет – это 1. Но вот значением переменной В, оказывается, будет число 2, а не 1. Почему? Дело в том, что имя N объявлено синонимом имени К, поэтому все вхождения имени N ассемблер будет заменять на имя К. Значит, директива В DW N понимается как директива В DW К. Но в этом месте текста программы константа К имеет значение 2, поэтому данная директива во­спринимается как В DW 2.

В то же время в примере справа переменные С и D получат одно и то же значение 11. Дело в том, что в директиве EQU указано, так сказать, настоящее константное выражение, и потому ассемблер вычисляет его сразу. Значение 11 этого выражения объявляется значением константы N, которая далее и будет обозна­чать это число.

Таким образом, необходимо внести следующее уточнение в действие директивы EQU: если в правой части директивы указано имя константы, то имя слева надо понимать не как имя константы (не как имя числа), а как синоним имени справа; если же в правой части ука­зано любое другое константное выражение, тогда имя слева действительно становится именем константы (обозначением числа). Что же касается директивы присваивания, то ее правая часть всегда вычисляется сразу и полученное число тут же становится новым значением константы.