|
6.
Директивы определения памяти
Директивы определения памяти служат для задания
размеров, содержимого и местоположения полей данный,
используемых в программе на языке ассемблера. В отличие от
других директив языка ассемблера при обработке директив
определения памяти генерируется объектный код. MASM
транслирует задаваемые в директивах определения памяти
числа, строки и выражения в отдельные образы байтов, слов
или других единиц данных. Эти образы копируются в объектный
файл.
Директивы определения данных могут задавать:
1. Скалярные данные, представляющие собой единичное значение
или набор единичных значений.
2. Записи, позволяющие манипулировать с данными на уровне
бит.
3. Структуры, отражающие некоторую логическую структуру
данных.
Директивы определения этих типов данных описаны в
следующих 3-х разделах.
6.1. Скалярные данных.
Директивы определения скалярных данных приведены в
таблице 6.1.
- 32 -
Таблица 6.1. Директивы определения скалярных данных.
________________________________________________________
| | |
| формат | функция |
|__________________________|___________________________|
| | |
| [[имя]] DB значение,... | определение байтов |
|__________________________|___________________________|
| | |
| [[имя]] DW значение,... | определение слов |
|__________________________|___________________________|
| | |
| [[имя]] DD значение,... | определение двойных слов |
|__________________________|___________________________|
| | |
| [[имя]] DQ значение,... | определение квадро-слов |
|__________________________|___________________________|
| | |
| [[имя]] DT значение,... | определение 10 байтов |
|__________________________|___________________________|
Директива DB обеспечивает распределение и
инициализацию 1 байта памяти для каждого из указанных
значений. В качестве значения может кодироваться целое
число, строковая константа, оператор DUP (см. ниже),
абсолютное выражение или знак ?. Знак ? обозначает
неопределенное значение. Значения, если их несколько, должны
разделяться запятыми.
Если директива имеет имя, создается переменная типа
BYTE с соответствующим данному значению указателя позиции
смещением.
Строковая константа может содержать столько символов,
сколько помещается на одной строке. Символы строки хранятся
в памяти в порядке их следования, т.е. 1-й символ имеет
самый младший адрес, последний - самый старший.
Директива DW обеспечивает распределение и
инициализацию слова памяти (2 байта) для каждого из
указанных значений. В качестве значения может кодироваться
целое число, 1- или 2-х символьная константа, оператор DUP
(см. ниже), абсолютное выражение, адресное выражение или
знак ?. Знак ? обозначает неопределенное значение. Значения,
если их несколько, должны разделяться запятыми.
Если директива имеет имя, создается переменная типа
WORD с соответствующим данному значению указателя позиции
смещением.
Строковая константа не может содержать более 2-х
символов. Последний (или единственный) символ строки
хранится в младшем байте слова. Старший байт содержит первый
символ или, если строка односимвольная, 0.
Директива DD обеспечивает распределение и
инициализацию двойного слова памяти (4 байта) для каждого из
- 33 -
указанных значений. В качестве значения может кодироваться
целое число, 1- или 2-х символьная константа, действительное
число, кодированное действительное число, оператор DUP (см.
ниже), абсолютное выражение, адресное выражение или знак ?.
Знак ? обозначает неопределенное значение. Значения, если их
несколько, должны разделяться запятыми.
Если директива имеет имя, создается переменная типа
DWORD с соответствующим данному значению указателя позиции
смещением.
Строковая константа не может содержать более 2-х
символов. Последний (или единственный) символ строки
хранится в младшем байте слова. Второй байт содержит первый
символ или, если строка односимвольная, 0. Остальные байты
заполняются нулями.
Директива DQ обеспечивает распределение и
инициализацию 8 байтов памяти для каждого из указанных
значений. В качестве значения может кодироваться целое
число, 1- или 2-х символьная константа, действительное
число, кодированное действительное число, оператор DUP (см.
ниже), абсолютное выражение, адресное выражение или знак ?.
Знак ? обозначает неопределенное значение. Значения, если их
несколько, должны разделяться запятыми.
Если директива имеет имя, создается переменная типа
QWORD с соответствующим данному значению указателя позиции
смещением.
Строковая константа не может содержать более 2-х
символов. Последний (или единственный) символ строки
хранится в младшем байте слова. Второй байт содержит первый
символ или, если строка односимвольная, 0. Остальные байты
заполняются нулями.
Директива DT обеспечивает распределение и
инициализацию 10 байтов памяти для каждого из указанных
значений. В качестве значения может кодироваться целое
выражение, упакованное десятичное число, 1- или 2-х
символьная константа, кодированное действительное число,
оператор DUP (см. ниже) или знак ?. Знак ? обозначает
неопределенное значение. Значения, если их несколько, должны
разделяться запятыми.
Если директива имеет имя, создается переменная типа
TWORD с соответствующим данному значению указателя позиции
смещением.
Строковая константа не может содержать более 2-х
символов. Последний (или единственный) символ строки
хранится в младшем байте слова. Второй байт содержит первый
символ или, если строка односимвольная, 0. Остальные байты
заполняются нулями.
При обработке директивы DT подразумевается, что
константы, содержащие десятичные цифры, представляют собой
не целые, а десятичные упакованные числа. В случае
необходимости определить 10-байтовое целое число следует
после числа указать спецификатор системы счисления (D или d
для десятичных чисел, H или h для 16-ричных и т.д.).
- 34 -
Если в одной директиве определения памяти заданы
несколько значений, им распределяются последовательные байты
памяти.
Во всех директивах определения памяти в качестве
одного из значений может быть задан оператор DUP. Он имеет
следующий формат:
счетчик DUP (значение,...)
Указанный в скобках () список значений повторяется
многократно в соответствии зо значением счетчика. Каждое
значение в скобках может быть любым выражением, имеющим
значением целое число, символьную константу или другой
оператор DUP (допускается до 17 уровней вложенности
операторов DUP). Значения, если их несколько, должны
разделяться запятыми.
Оператор DUP может использоваться не только при
определении памяти, но и в других директивах.
Примеры директив определения скалярных данных:
integer1 DB 16
string1 DB 'abCDf'
empty1 DB ?
integer2 DW 16728
contan2 DW 4*3
multip2 DW 1,'$'
arr2 DW array
string3 DD 'ab'
real3 DD 1.5
encode3 DD 3F000000r
high3 DD 4294967295
char4 DQ 'b'
encode4 DQ 3F00000000000000r
high4 DQ 18446744073709551615
pack5 DT 1234567890
real5 DT 1.5
mult5 DT 'a',3F000000000000000000r
high5 DT 1208925819614629174706175d
db6 DB 5 DUP(5 DUP(5 DUP(10)))
dw6 DW DUP(1,2,3,4,5)
6.2. Записи.
Запись представляет собой набор полей бит,
объединенных одним именем. Каждое поле записи имеет
- 35 -
собственную длину, исчисляемую в битах, и не обязана
занимать целое число байтов.
Объявление записи в программе на языке ассемблера
включает в себя 2 действия:
1. Объявление шаблона или типа записи директивой
RECORD.
2. Объявление собственно записи.
Формат директивы RECORD:
имя-записи RECORD имя-поля:длина[[=выражение]],...
Директива RECORD определяет вид 8- или 16-битовой
записи, содержащей одно или несколько полей. Имя-записи
представляет собой имя типа записи, которое будет
использоваться при объявлении записи. Имя-поля и длина (в
битах) описывают конкретное поле записи. Выражение, если оно
указано задает начальное (умалчиваемое) значение поля.
Описания полей записи в директиве RECORD, если их
несколько, должны разделяться запятыми. Для одной записи
может быть задано любое число полей, но их суммарная длина
не должна превышать 16 бит.
Длина каждого поля задается константой в пределах от 1
до 16. Если общая длина полей превышает 8 бит, ассемблер
выделяет под запись 2 байта, в противном случае - 1 байт.
Если задано выражение, оно определяет начальное
значение поля. Если длина поля не меньше 7 бит, в качестве
выражения может быть использован символ в коде ASCII.
Выражение не должно содержать ссылок вперед.
Внутри записи поля размещаются слева направо в порядке
описания в директиве RECORD. Поэтому объявленное первым поле
содержит самые значимые биты записи, если рассматривать ее
как двоичное число. Если суммарная длина полей не равна 8
или 16, запись расширяется до целой границы байта нулевыми
битами слева, и, таким образом, последний бит последнего
поля всегда является самым младшим битом записи.
Пример:
item RECORD char:7='Q',weight:4=2
Запись item будет иметь следующий вид:
char weight
___________ _____
| | | |
0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 0
При обработке директивы RECORD формируется шаблон
записи, а сами данные создаются при объявлении записи,
которое имеет следующий вид:
- 36 -
[[имя]] имя-записи <[[значение,...]]>
По такому объявлению создается переменная типа записи
с 8- или 16-битовым значением и структурой полей,
соответствующей шаблону, заданному директивой RECORD с
именем имя-записи.
Имя задает имя переменной типа записи. Если имя
опущено, MASM распределяет память, но не создает переменную,
которую можно было бы использовать для доступа к записи.
В скобках <> указывается список значений полей записи.
Значения в списке, если их несколько, должны разделяться
запятыми. Каждое значение может быть целым числом, строковой
константой или выражением и должно соответствовать длине
данного поля. Для каждого поля может быть задано одно
значение.
Скобки <> обязательны, даже если начальные значения не
заданы.
Если в качестве значения используется оператор DUP
(п.6.1), в скобки <> следует заключать список значений
оператора DUP. Следует иметь ввиду, что при использовании
оператора DUP создается несколько переменных типа запись.
Задавать значения всех полей записи необязательно.
Если ассемблер вместо значения обнаружит левый пробел, будет
использовано начальное значение поля, заданное директивой
RECORD, а если оно и там опущено, значение поля будет
неопределено.
Пример:
table item 10 DUP(<'A',2>)
Если для описания шаблона записи использовалась
директива RECORD из предыдущего примера, по этому объявлению
создается 10 записей, объединенных именем table. Каждая
запись будет иметь следующий вид:
char weight
___________ _____
| | | |
0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0
6.3. Структуры.
Структура представляет собой набор полей байтов,
объединенных одним именем.
Объявление структуры в программе на языке ассемблера
включает в себя 2 действия:
- 37 -
1. Объявление шаблона или типа структуры директивами
STRUC и ENDS.
2. Объявление собственно структуры.
Формат объявления типа структуры:
имя STRUC
описания-полей
имя ENDS
Директивы STRUC и ENDS обозначают соответственно
начало и конец описания шаблона (типа) структуры. Описание
типа структуры задает имя типа структуры и число, типы и
начальные значения полей структуры.
Указанное в директивах STRUC и ENDS имя задает новое
имя типа структуры. Оно должно быть уникальным.
Описания-полей определяют поля структуры и могут быть заданы
в одной из следующих форм:
[[имя]] DB значение,...
[[имя]] DW значение,...
[[имя]] DD значение,...
[[имя]] DQ значение,...
[[имя]] DT значение,...
Каждое поле может иметь свое имя. Директивы DB, DW,
DD, DQ или DT задают длину поля. Для каждого поля могут быть
указаны начальные значения, которыми инициализируются поля
при отсутствии соответствующих начальных значений
при объявлении структуры. Имя каждой директивы, если оно
задано, должно быть уникальным и представляет смещение
поля относительно начала структуры.
Значением поля может быть число, символ, строковая
константа или имя другого объекта. Для определения множества
значений поля может использоваться оператор DUP. Если в
качестве значения задана строковая константа, поле занимает
столько байтов, сколько символов в константе. Если задано
несколько значений, они должны разделяться запятыми.
Объявление типа структуры может содержать только
описания полей и комментарии. По этой причине структуры не
могут быть вложенными.
Пример:
table STRUC
count DB 10
value DW 10 DUP(?)
tname DB 'font'
table ENDS
При обработке директив STRUC и ENDS формируется шаблон
структуры, а сами данные создаются при объявлении структуры,
которое имеет следующий вид:
- 38 -
[[имя]] имя-структуры <[[значение,...]]>
По такому объявлению создается переменная типа
структура со структурой полей, соответствующей шаблону,
заданному директивой STRUC с именем имя-структуры.
Имя задает имя переменной. Если имя опущено, MASM
распределяет память, но не создает переменную, которую можно
было бы использовать для доступа к структуре.
В скобках <> указывается список значений полей
структуры. Значения в списке, если их несколько, должны
разделяться запятыми. Каждое значение может быть целым
числом, строковой константой или выражением, тип которого
должен совпадать с типом соответствующего ему поля. Для
каждого поля может быть задано одно значение.
Скобки <> обязательны, даже если начальные значения не
заданы.
Если в качестве значения используется оператор DUP
(п.6.1), в скобки <> следует заключать список значений
оператора DUP.
Задавать значения всех полей структуры необязательно.
Если ассемблер вместо значения обнаружит левый пробел, будет
использовано начальное значение поля, заданное при описании
типа структуры, а если и оно опущено, значение поля будет
неопределено.
Следует помнить, что объявлении структуры нельзя
задавать значения полей, для которых в соответствующем
шаблоне задано множество значений. Например:
strings STRUC
buffer DB 100 DUP(?)
crif DB 13,10
guery DB 'Filename'
endm DB 35
strings ENDS
При объявлении структуры с использованием этого
шаблона значения полей buffer и crif не могут быть заданы,
т.к. шаблон для них определяет множество значений. Значение
поля guery может быть перекрыто только значением, длина
которого не превышает 8 байтов. Аналогично, значение поля
endm может быть перекрыто любым однобайтовым значением.
© KOAP
Open Portal 2000
|