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». Определение символьной константы с таким значением даст похожий результат, различие лишь в том, что имя макроинструкции будет распознаваться только как мнемоник инструкции. Также, макроинструкции заменяются соответствующим кодом даже перед заменой символьных констант на их значения. То есть, если вы вы определите макроинструкцию и символьную константу под одним и тем же именем и используете это имя как мнемоник инструкции, оно будет заменено на содержание макроинструкции, но если вы используете его внутри операндов, имя будет заменено на значение символьной константы.
Читать дальше