Начальное значение инициализированной переменной должно представлять собой константу, но это не обязательно должно быть число. Можно также использовать выражения:
TestVar DW ((924/2)+1)
а также метки:
.DATA
Buffer DW 16 DUP (0)
BufferPointer DW Buffer
Когда в качестве операнда директивы определения данных ис-пользуется метка, то используется значение самой метки, а не зна-чение, записанное по этой метке. В последнем примере начальное значение BufferPointer представляет собой смещение Buffer в сег-менте .DATA, а не значение 0, которое хранится в переменной Buffer (как если бы для инициализации BufferPointer использова-лось OFFSET Buffer). Другими словами, с учетом такой инициализа-ции BufferPointer, и инструкция:
mov ax,OFFSET Buffer
и инструкция:
mov ax,[BufferPointer]
загрузят в регистр AX одно и то же значение (смещение переменной Buffer).
В выражениях определения данных допускается использовать метки. Например, в следующем фрагменте программы переменная WordArrayLength инициализируется значением длины (в байтах)
WordArray:
.DATA
WordArray DW 50 DUP (0)
WordArrayEnd LABEL WORD
WordArrayLength DW (WordArrayEnd — WordArray)
Если вы хотите вычислить длину переменной WordArray в сло-вах, а не в байтах, это можно сделать, просто разделив длину в байтах на 2:
WordArrayLength DW (WordArrayEnd — WordArray) / 2
Неинициализированные данные
Иногда нет смысла присваивать переменной памяти начальное значение. Предположим, например, что ваша программа считывает следующие 10 набранных на клавиатуре символов и записывает их в массив с именем KeyBuffer:
mov cx,10 ; число символов, которые
; требуется считать
mov bx,OFFSET KeyBuffer ; символы будут
; сохранены в KeyBuffer GetKeyLoop:
mov ah,1 ; функция DOS ввода с
; клавиатуры
int 21h ; получить следующий
; нажатый символ
mov [bx],al ; сохранить символ
inc cx ; ссылка на ячейку
; памяти для следующего
; символа
loop GetKeyLoop
Инициализировать KeyBuffer можно следующим образом:
KeyBuffer DB 10 DUP (0)
но смысла в этом немного, так как начальные значения массива KeyBuffer будут немедленно перезаписаны в цикле GetKeyLoop. Все, что здесь в действительности нужно — это определить переменную в памяти, как неинициализированную. Турбо Ассемблер предусматривает такую возможность с помощью символа «знак вопроса» (?).
Вопросительный знак указывает Турбо Ассемблеру, что вы ре-зервируете ячейку памяти, но не инициализируете ее. Например, в последнем примере KeyBuffer можно определить так:
KeyBuffer DB 10 DUP (?)
В данной строке резервируется 10 байт памяти, начиная с мет-ки Keybuffer, но этим байтам не присваивается никакого конкретно-го значения.
Конечно, каждый раз, когда вы используете неинициализирован-ную переменную в памяти, вы должны быть уверены в том, что вы инициализируете ее в своей программе перед тем, как использовать эту переменную. Например, было бы ошибочным использовать содержи-мое KeyBuffer в последнем примере до того, как этот массив будет заполнен, так как находящиеся в KeyBuffer начальные значения не-определены.