В числовых выражениях можно также использовать вместо чисел константы или метки. Для описания констант и меток используются специальные директивы. Каждая метка должна быть определена только один раз, и она будет доступна из любого места кода (даже до ее определения). Константа может изменяться много раз, но в этом случае она доступна только после присвоения, и она всегда равна значению из последнего определения перед местом, где она используется. Если константа определена только один раз в исходном коде, то она, как и метка, доступна из любого места.
Определение константы состоит из имени константы, знака = и числового выражения, которое после вычисления станет значение константы. Это значение вычисляется в то же время, что и происходит определение константы. Например, можно определить константу count, используя директиву count=17, а затем использовать ее в инструкциях, таких как mov cx,count, которая в процессе компиляции станет инструкцией mov cx,17.
Существуют различные способы определения меток. Простейший вариант ‑ это указать двоеточие за названием метки. За такой директивой даже может следовать инструкция в той же строке. Такая директива определяет метку, значение которой равно смещению точки, где она определена. Этот метод обычно используется для обозначения мест в коде. Другой способ заключается в указании имени метки (без двоеточия) перед какой-нибудь директивой описания данных. Это определение присваивает метке значение смещения начала определенных данных, и запоминается как метка данных с размером ячейки, указанной директивой из таблицы 1.3.
Метка может рассматриваться как постоянное значение, равное смещению помеченного кода или данных. Например, если при описании данных с помощью директивы метки char db 224, необходимо поместить в регистр bx смещение (адрес) этих данных, то надо использовать инструкцию mov bx,char. Если же в регистр dl надо поместить значение байта, адресуемое меткой char, то необходимо использовать инструкцию mov dl,[char] (или mov dl, ptr char). Но если вы попытаетесь скомпилировать инструкцию mov ax,[char], то она вызовет ошибку, потому что FASM сравнивает размеры операндов, которые должны быть равны. Тем не менее, можно заставить fasm прокомпилировать данную инструкцию, изменив размер операнда: mov ax, word [char], но помните, что она будет читать два байта, начиная с адреса char, хотя данная метка объявлена как однобайтная.
Последний и наиболее гибкий способ описания метки является использование директивы label. Обязательным операндом для этой директивы является имя метки. Далее дополнительно может следовать размер оператора, а затем, также необязательно, оператор at и числовое выражение, определяющее адрес, на который создаваемая метка будет ссылаться. Например, директива label wchar word at char определяет новую метку для 16-битных данных по адресу char. Теперь инструкция mov ax,[wchar] после компиляции будет такая же, как и инструкция mov ax, word [char]. Если адрес не указан, директива label будет ссылаться на текущий адрес. Таким образом, инструкция mov [wchar],57568 скопирует два байта, а инструкция mov [char],224 скопирует один байт на тот же адрес.
Метка, имя которой начинается с точки, рассматривается как локальная метка, и ее имя, связывается с именем последней глобальной метки (имя, которой начинается с любого допустимого знака кроме точки) для создания полного имени этой метки. Таким образом, можно использовать короткое имя (начинающееся с точки) этой метки в любом месте до описания следующей глобальной метки, а в других местах необходимо использовать полное имя. Метки, начинающиеся с двух точек являются исключением ‑ они похожи на глобальные, но не могут выступать в качестве префикса для локальных меток.
Имя @@ ‑ означает анонимную метку, ее можно объявить несколько раз в коде. Символ @b (или его эквивалент @r) ссылается на ближайшую предыдущую анонимную метку, а символ @f ссылается на ближайшую следующую анонимную метку. Эти специальные символом и они не чувствительны к регистру.