Инициализация выражений и меток


Начальное значение инициализированной переменной должно представлять собой константу, но это не обязательно должно быть число. Можно также использовать выражения:

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 начальные значения не-определены.