До сих пор мы видели только, как можно присваивать имена ячейкам памяти с помощью метки, предшествующей директиве опреде-ления данных (например, DB). Другой удобный способ присваивать имя ячейке памяти предоставляет директива LABEL.
Директива LABEL позволяет вам определить как имя метки, так и ее тип, не определяя при этом данные. Вот, например, еще один способ, с помощью которого можно определить в предыдущем примере массив KeyBuffer:
KeyBuffer LABEL BYTE
DB 10 DUP (?)
Типы меток, которые можно определить с помощью директивы LABEL, включают в себя:
BYTE PWORD FAR
WORD QWORD PROC
DWORD TBYTE UNKNOWN
FWORD NEAR
Типы BYTE (байт), WORD (слово), DWORD (двойное слово), PWORD, QWORD и TBYTE говорят сами за себя, определяя, соответст-венно, 1-, 2-, 4-, 6-, 8- и 10-байтовые элементы данных. Приведем пример инициализации переменной памяти, как пары байт, и обраще-ния к ней, как к слову:
.DATA
WordVar LABEL WORD
DB 1,2
.CODE
mov ax[WordVar]
Когда эта программа выполняется, в регистр AL загружается 1 (первый байт WordVar), а в регистр AH — значение 2.
Ключевые слова NEAR и FAR используются в программе для выбо-ра типа вызова или перехода, необходимого для достижения опреде-ленной метки. Например, в программе:
.CODE
FarLabel LABEL FAR
NearLabel LABEL NEAR
mov ax,1
jmp FarLabel
jmp NearLabel
первая инструкция JMP представляет собой переход дальнего типа (загружаются оба регистра CS и IP), так как это переход на метку типа FAR, а второй переход имеет ближний тип (загружается только регистр IP), так как это переход на метку типа NEAR. Заметим, что обе метки FarLabel и NearLabel описывают один и тот же адрес (ад-рес инструкции MOV), но позволяют вам переходить на него различ-ными способами.
Когда вы используете упрощенные директивы определения сег-ментов, то директива PROC — это удобный способ определить метку нужного типа (ближнюю или дальнюю) для текущей модели кода. Когда используется сверхмалая, малая или компактная модель памяти, то LABEL PROC — это то же самое, что LABEL FAR. Это означает, что если вы измените модель памяти, вы также можете автоматически из-менить определенные метки.
Например, в программе:
DOSSEG
.MODEL small
.CODE
EntryPoint LABEL PROC
метка EntryPoint имеет ближний тип, но если вы измените модель памяти на большую, то это будет метка дальнего типа. Обычно для определения тех точек входа, которые вы хотели бы изменить при изменении модели памяти вместо директивы LABEL используют дирек-тиву PROC (см. далее раздел «Подпрограммы»), однако иногда требу-ется иметь несколько точек входа в подпрограмму, и вам потребует-ся директива LABEL.
Наконец, мы подошли к директиве LABEL UNKNOWN. Ключевое сло-во UNKNOWN (неизвестно) — это просто способ указать, что вы не уверены насчет типа данных используемой метки. Если вы знакомы с языком Си, то UNKNOWN аналогично типу языка Си void. В качестве примера UNKNOWN предположим, что у вас имеется переменная памяти TempVar, к которой иногда нужно обращаться, как к байту, а иногда — как к слову. С помощью LABEL UNKNOWN это делается в следующей программе:
.DATA
TempVar LABEL UNKNOWN
DB ?,?
.CODE
mov [TampVar],ax
add di,[TempVar]
