Именованные ячейки памяти


До сих пор мы видели только, как можно присваивать имена ячейкам памяти с помощью метки, предшествующей директиве опреде-ления данных (например, 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]