2.3.2 Символьные константы
Символьные константы отличаются от числовых констант тем, что перед процессом ассемблирования они заменяются на их значения во всех строках кода, следующих за их определением, и все может стать их значением.
Определение символьных констант состоит из имени константы, за которой следует директива « equ
». Все, что следует за этой директивой, станет значением константы. Если значение символьной константы содержит другие символьные константы, они заменяются на их значения перед присвоением значения новой константе. Например:
d equ dword
NULL equ d 0
d equ edx
После этих трех определений значение « NULL
» будет « dword 0
», а значение « d
» будет « edx
». Так, например, « push NULL
» будет сассемблировано как « push dword 0
», а « push d
» как « push edx
». А, например, в такой строке:
d equ d,eax
константе « d
» будет присвоено новое значение « edx,eax
». Таким образом могут определяться растущие списки символов.
« restore
» позволяет присвоить назад предыдущее значение переопределенной константы. За ней должно следовать одно или больше имен символьных констант, разделенных запятыми. Так, « restore d
» после предыдущего переопределения вернет константе значение « edx
», следующее применение этой директивы вернет ей значение « dword
», а ещё одно применение восстановит первоначальное значение, как будто такая константа не определялась. Если не константа с заданным именем не определена, то « restore
» не вызовет ошибку, а будет просто проигнорирована.
Символьные константы могут использоваться для адаптации синтаксиса ассемблера к персональным предпочтениям. Например, следующие определения создают удобные ярлыки для всех операторов размера:
b equ byte
w equ word
d equ dword
p equ pword
f equ fword
q equ qword
t equ tword
x equ dqword
Так как символьная константа может так же иметь пустое значение, она может использоваться для того, чтобы допустить синтаксис со словом « offset
» перед каким-нибудь значением адреса:
offset equ
После такого определения « mov ax, offset char
» будет правильной конструкцией, которая будет копировать смещение переменной « char
» в регистр « ax
», так как « offset
» заменяется пустым значением, и поэтому игнорируется.
Символьные константы могут также быть определены директивой « fix
», которая имеет такой же синтаксис, как « equ
», но определяет константы высшего приоритета — они заменяются их символическим значением даже перед совершением директив препроцессора и макроинструкций. Исключением является сама директива « fix
», которая имеет наивысший возможный приоритет, и поэтому допускает переопределение констант, заданных таким путем. Но если такие константы высшего приоритета находятся внутри значения, следующего за директивой « fix
», они заменяются их значениями перед присвоением этого значения новой константе.
Директива « fix
» может использоваться для адаптирования директив препроцессора, что нельзя сделать директивой « equ
». Например:
incl fix include
определяет короткое имя для директивы « include
», тогда как такое же определение директивой « equ
» не даст такого результата, так как стандартные символьные константы заменяются на из значения после поиска строк с директивами препроцессора.
« macro
» позволяет вам определить собственный комплекс инструкций, называемых макроинструкциями. Их использование может существенно упростить процесс программирования. В своей простейшей форме директива похожа на описание символьной константы. Например, следующая строка определяет ярлык для инструкции « test al,0xFF
»:
macro tst {test al,0xFF}
После директивы « macro
» должно идти имя макроинструкции и далее её содержание, заключенное между знаками « {
» и « }
». Вы можете использовать инструкцию « tst
» в любом месте после её определения и она будет ассемблирована как « test al,0xFF
». Определение символьной константы с таким значением даст похожий результат, различие лишь в том, что имя макроинструкции будет распознаваться только как мнемоник инструкции. Также, макроинструкции заменяются соответствующим кодом даже перед заменой символьных констант на их значения. То есть, если вы вы определите макроинструкцию и символьную константу под одним и тем же именем и используете это имя как мнемоник инструкции, оно будет заменено на содержание макроинструкции, но если вы используете его внутри операндов, имя будет заменено на значение символьной константы.
Читать дальше