Строки исходного кода на языке Ассемблера имеют следующий формат:
<метка> <инструкция/директива> <операнды> <;комментарий>
где <метка> представляет собой необязательное имя идентификатора, <инструкция/директива> это мнемоника инструкции или директивы, <операнды> содержат сочетание 0, 1 или 2 (иногда более) констант, ссылок на память или регистры, или текстовых строк, как это требуется в каждой конкретной инструкции или директиве, <;комментарий> необязательный комментарий.
В любом месте в строки качестве символа продолжения строки можно поместить символ обратной косой черты (\). Однако данный символ нельзя использовать для разбиения идентификаторов. Обратная косая черта означает: «считать следующую строку, и продолжить обработку с данной точки». При этом вы можете комментировать каждую строку. Например:
foo mystructure \ ; Начать заполнение структуры
<0, \ ; Сначала нулевое значение
1, \ ; Затем единица
2> \ ; Cтруктура завершается значением 2
В двух контекстах символы продолжения строки не распознаются. В общем случае они не распознаются в любом контексте, где символы обрабатываются как текст, а не как идентификаторы, числа или строки, либо в режиме MASM, когда продолжение строки используется в первых двух идентификаторах оператора. Например:
ifdif <123\>,<456\>
Здесь два вложенных символа «\» не распознаются, как продолжение строки.
comment \
:
начинает блок комментария, а не определяет идентификатор ближнего типа с именем COMMENT.
Символ продолжения строки не распознается также внутри макроопределений. Однако он распознается при расширении макрокоманды.
Давайте рассмотрим каждый из этих элементов более подробно.
Метки
Метки это ни что иное, как имена, использующиеся в программе для ссылки на числа и строки символов или ячейки памяти. Метки позволяют вам присваивать имена переменным в памяти, значениям и адресам, где находятся конкретные инструкции. Например, в следующей программе, которая вычисляет факториал 5, используется несколько меток:
DOSSEG
MODEL SMALL
STACK 200h
.DATA
FactorialValue DW ?
Factorial DW ?
.CODE
FiveFactorial PROC
mov ax,@Data
mov ds,ax
mov [FactorialValue],1
mov [Factorial],2
mov cx,4
FiveFactorialLoop:
mov ax,[FactorialValue]
mul [Factorial]
mov [FactorialValue],ax
inc [Factorial]
loop FiveFactorialLoop
ret
FiveFactorial ENDP
END
Метки FactorialValue и Factorial эквивалентны адресам двух 16битовых переменных. Они используются для последующей ссылки в программе на эти две переменные. Метка FiveFactorial это имя подпрограммы (процедуры или функции), содержащей код. Она позволяет вызывать этот код в других частях программы. Наконец, метка FiveFactorialLoop эквивалентна адресу инструкции:
mov ax,[FactorialValue]
благодаря которой оператор LOOP в конце программы может осуществлять обратный переход на эту инструкцию.
Метки могут состоять из следующих символов:
A Z a z _ @ $ ? 0 9
В режиме MASM допускается также точка (.) (см. Главу 11), но только в качестве первого символа. Цифры 0 9 не могут использоваться в качестве первых символов метки. Символы $ и ? имеют специальное значение, поэтому их не следует использовать в именах ваших идентификаторах.
Каждая метка должна определяться только один раз, то есть метки должны быть уникальными. (Из этого правила есть исключения. Например, специальные метки, определенные с помощью директивы =, локальные метки в макрокомандах и подпрограммы режима Ideal). Как операнды метки могут использоваться любое число раз.
Метка может занимать всю строку, то есть на этой строке кроме метки может отсутствовать инструкция или директива. В этом случае значением метки является адрес инструкции или директивы на следующей строке программы. Например, во фрагменте программы:
jmp DoAddition
DoAddition:
add ax,dx
следующей инструкцией, выполняемой после инструкции JMP, которая выполняет переход на метку DoAddition, является инструкция ADD AX,DX. Предыдущий пример эквивалентен следующему:
jmp DoAddition
DoAddition: add ax,dx
(Список директив приведен в Главе 3 «Справочного руководства», а о регистрах процессора 8086 рассказывается в Главе 4.)
В размещении каждой метки на своей собственной строке имеются два преимущества. Вопервых, когда вы размещаете каждую метку на отдельной строке, легче использовать длинные метки без нарушения структуры (формата) программы на Ассемблере, что сделало бы ее менее читабельной. Вовторых, справа от метки легче добавить новую инструкцию, если метка не находится на той же строке, что и инструкция. Чтобы преобразовать последний пример к виду:
jmp DoAddition
DoAddition: mov dx,[MemVar]
add ax,dx
вам пришлось бы разделить строку с меткой DoAddition и добавить новый текст. Если же DoAddition находится на отдельной строке, вы можете просто добавить после этой метки новую строку.
