Выбрать главу

Директива «dp» или её синоним «df» допускают, чтобы значения состояли из двух числовых выражений, разделенных двоеточием, где первое значение — это верхнее слово, а второе — это нижнее двойное слово значения дальнего указателя. Также «dd» допускает такие указатели, состоящие из двух слов, разделенных двоеточием, и «dt» допускает слово и четверное слово, разделенные двоеточием, четверное слово запоминается первым. Директива «dt» с одним параметром допускает только значения с плавающей точкой и создает данные в FPU-формате двойной расширенной точности.

Все вышеперечисленные директивы поддерживают использование специального оператора «dup» для создания копий данных значений. Количество дубликатов должно стоять перед этим оператором, а их значение должно стоять после — это может быть даже цепь значений, разделенных запятыми, но эта цепь должна быть заключена в скобки, например «db 5 dup (1,2)» определяет пять копий данной последовательности из двух байтов.

«file» — это специальная директива и её синтаксис может быть различным. Эта директива включает цепь байтов из файла. В качестве параметра за ней должно идти в кавычках имя файла, далее, опционально, двоеточие и числовое выражение, указывающее начало цепочки байтов, далее, также опционально, запятая и числовое выражение, определяющее количество байтов в этой цепочке (если этот параметр не определен, то будут включены все данные до конца файла). Например, «file 'data.bin'» включит весь файл как двоичные данные, а «file 'data.bin':10h,4» включит только четыре байта, начиная со смещения 10h.

За директивой резервирования данных должно следовать одно числовое выражение, значение которого определяет количество резервируемых ячеек установленного размера. Все директивы описания данных также поддерживают значение «?», которое значит, что этой ячейке не должно быть присвоено какое-то значение. Эффект от этой директивы такой же, как от директивы резервирования данных. Неинициализированные данные не могут быть включены в файл вывода, и, таким образом, их значения всегда будут считаться неизвестными.

1.2.3 Константы и метки

В числовых выражениях вместо чисел вы также можете использовать константы и метки. Чтобы назначить их, используйте специальные директивы. Каждая метка может быть определена только однажды и она будет доступна из любой части кода (даже перед местом, где она была определена). Константа может быть переопределена много раз, но в этом случае она будет доступна только после присвоения значения и всегда будет равна значению из последнего определения перед местом, в котором она использована. Если константа определена лишь однажды, она, так же как и метка, доступна из любой части кода.

Определение константы состоит из имени константы, знака «=» и числового выражения, которое после вычисления становится значением константы. Это значение всегда вычисляется в то же время, что и определение константы. Например, с помощью директивы «count = 17» вы можете определить константу «count» и после использовать её в инструкциях ассемблера, таких как «mov cx,count» — которая превратится в «mov cx,17» во время процесса компиляции.

Существуют разные способы определения меток. Простейший из них — двоеточие после названия метки. За этой директивой на той же строке даже может следовать другая инструкция. Она определяет метку, значение которой равно смещению точки, в которой она определена. Этот метод обычно используется, чтобы пометить места в коде. Другой способ — это следование за именем метки (без двоеточия) какой-нибудь директивы описания данных. Метке присваивается значение адреса начала определенных в директиве данных и запоминается компилятором как метка для данных с размером ячейки, заданной директивой из таблицы 1.3.

Метка может быть обработана как константа со значением, равным смещению помеченного кода или данных. Например, если вы определяете данные, используя помеченную директиву «char db 224», для того, чтобы поместить адрес начала этих данных в регистр BX, вам нужно использовать инструкцию «mov bx,char», а для того, чтобы поместить в регистр DL значение байта, на который ссылается «char», нужно использовать «mov dl,[char]» (или «mov dl,ptr char»). Если вы попытаетесь ассемблировать «mov ax,[char]», FASM выдаст ошибку, так как он сравнивает размеры операндов, которые должны быть равны. Вы можете принудительно проассемблировать эту инструкцию, изменяя размер операнда: «mov ax, word [char]», но помните, что эта инструкция прочитает два байта, начинающихся с адреса «char», тогда как он был определен как один байт.