Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Директивы условного ассемблирования



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

Блок предложений условного ассемблирования имеет следующий общий вид:

директива-условного-ассемблирования

..........

предложения Ассемблера или инструкции

..........

[[ ELSE ]]

..........

предложения Ассемблера или инструкции

..........

ENDIF

Директива-условного-ассемблирования задает условие, при истинном значении которого будут ассемблироваться предложения, расположенные непосредственно после директивы и до ключевого слова ELSE, или, если оно опущено, до конца блока, обозначаемого ENDIF. Если условие не выполняется, ассемблируется группа предложений, расположенная между ключевыми словами ESLE и ENDIF, а если ELSE опущено, MASM пропускает блок.

Допускается вложенность директив. Максимальная глубина вложения — 255.

В качестве директивы-условного-ассемблирования могут задаваться конструкции, приведенные ниже.

 

 

Директивы условного ассемблирования:

IF выражение

IFE выражение

IF1

IF2

IFDEF имя

IFNDEF имя

IFB < аргумент>

IFNB < аргумент>

IFIDN < аргумент-1>, < аргумент-2>

IFDIF < аргумент-2>, < аргумент-2>

В случае директивы IF блок ассемблируется, если указанное выражение истинно (не нуль). Для директивы IFE блок ассемблируется, если выражение ложно (нуль). Выражение должно иметь абсолютное значение и не может содержать ссылок вперед.

Директивы IF1 и IF2 проверяют номер прохода Ассемблера и обеспечивают обработку блока только на 1-м ( IF1 ) или только на 2-м ( IF2 ) проходе.

Пример (выдача сообщений на консоль):

IF1

%OUT Pass 1

ELSE

%OUT Pass 2

ENDIF

Директивы IFDEF и IFNDEF проверяют, определено ли в программе указанное имя. IFDEF обеспечивает ассемблирование, если это имя определено как метка, переменная или символ, IFNDEF — если имя не определено. Заметим, что если в качестве имени задана ссылка вперед, она считается неопределенной на 1-м проходе и определенной на
2-м.

Имена можно определять не только указанием их в соответствующей позиции при мнемонике инструкции или директивах определения памяти, но в опции Ассемблера /D, что позволяет управлять составом ассемблируемой программы без изменения исходного файла.

Директивы IFB и IFNB проверяют значение указанного аргумента, трактуемого как строка символов, и вызывают ассемблирование блока, если аргумент является пробелом ( IFB ) или отличен от пробела ( IFNB ). Аргумент может быть именем, числом или выражением. Скобки < и > обязательны.

Директивы IFB и IFNB введены для использования их в макроопределениях, где они могут управлять условным ассемблированием, основываясь на том, задан или нет параметр макроопределения. В этом случае в качестве аргумента следует задавать один из формальных параметров макроопределения.

Директивы IFDIF и IFIDN сравнивают специфицированные для них аргументы, которые трактуются как символьные строки (с учетом регистра), и вызывают ассемблирование блока при их идентичности ( IFIDN ) или неидентичности ( IFDIF ). Аргументы могут быть именами, числами или выражениями. Скобки < и > обязательны. Аргументы разделяются запятой.

Директивы IFDIF и IFIDN введены для использования их в макроопределениях, где они могут управлять условным ассемблированием, анализируя значения передаваемых в макроопределение параметров. В этом случае в качестве аргументов следует задавать формальные параметры макроопределения.

Директивы условной генерации ошибок

Использование директив условной генерации ошибок позволяет контролировать ситуации, не нашедшие отражения в синтаксисе языка Ассемблера.

Например, при помощи такой директивы можно вызвать генерацию сообщения об ошибке и, соответственно, установку минимального кода возврата транслятора в случае использования регистра AX, что с точки зрения синтаксиса не является ошибкой, но может быть недопустимо по логике программы.

Обработка любой директивы условной генерации ошибок, кроме.ERR1, с истинным условием эквивалентна распознаванию фатальной ошибки (с кодом возврата 7), при которой MASM уничтожает объектный файл.

Форматы директив и соответствующие им сообщения MASM приведены ниже.

 

Директивы условной генерации ошибок:

Синтаксис Номер и текст сообщения

ERR1 87 Forced error — pass 1

ERR2 88 Forced error — pass 2

ERR 89 Forced error

ERRE выражение 90 Forced error — expression equals 0

ERRNZ выражение 91 Forced error — expression not equals 0

ERRNDEF имя 92 Forced error — symbol not defined

ERRDEF имя 93 Forced error — symbol defined

ERRB < строка> 94 Forced error — string blank

ERRNB < строка> 95 Forced error — string not blank

ERRIDN < строка-1> 96 Forced error — strings identical < строка-2>

ERRDIF < строка-2> 97 Forced error — strings different < строка-2>

Директива.ERR обеспечивает безусловную генерацию сообщения об ошибке. Директивы.ERR1 и.ERR2 также безусловно воздействуют соответственно лишь на 1-й и 2-й проход транслятора. Директива.ERR1 вызывает не фатальную ошибку, а предупреждение.

Директивы.ERRNZ и.ERRE вычисляют значение указанного выражения и обеспечивают появление сообщения об ошибке соответственно в случае истинности (1) или ложности (0) этого выражения.

Директива.ERRDEF обеспечивает появление фатальной ошибки, когда указанное имя определено в программе как метка, переменная или символ, а директива.ERRNDEF — когда имя еще не определено. Если это имя является ссылкой вперед, оно считается неопределенным на 1-м проходе и определенным на 2-м. Эти директивы работают на 1-м проходе.

Директивы.ERRB и.ERRNB анализируют указанную строку и обеспечивают генерацию сообщения об ошибке, если эта строка соответственно содержит все пробелы или нет.

Директивы.ERRIDN и.ERRDIF вызывают появление фатальной ошибки, если указанные строки соответственно идентичны или различны.

 

 

Макросредства

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

Макрокоманда может встречаться в исходной программе столько раз, сколько это необходимо. Макроопределение в исходном файле должно предшествовать его первому использованию в макрокоманде. Макроопределение может как непосредственно находиться в тексте программы, так и подключаться из другого файла директивой INCLUDE.

В макроопределение могут быть переданы параметры, которые могут управлять макроподстановкой или задавать фрагменты текста.

В программе на языке Ассемблера макрокоманды выполняют в целом те же функции, что и процедуры, то есть, обеспечивают многократное и функционально законченное действие с параметрическим управлением.

Различие заключается в следующем:

u Процедура присутствует в исходной программе один раз, тогда как тело макроопределения дублируется столько раз, сколько соответствующих макрокоманд содержит исходный файл.

u Текст процедуры статичен и неизменен в то время, как состав макрорасширения может зависеть от параметров макрокоманды. Следует помнить, что параметры макрокоманды — это значения времени ассемблирования, а параметры процедуры принимают какие-то определенные значения лишь в процессе выполнения программы.

 

Макродирективы

Макроопределение представляет собой блок исходных предложений, начинающийся директивой MACRO и заканчивающийся директивой ENDM. Формат макроопределения:

имя MACRO [[формальный-параметр,...]]

предложения

ENDM

Именем макроопределения считается имя, указанное в директиве MACRO. Оно должно быть уникальным и используется в исходном файле для вызова макроопределения. Формальные параметры представляют собой внутренние по отношению к данному макроопределению имена, которые используются для обозначения значений, передаваемых в макроопределение при его вызове. Может быть определено любое число формальных параметров, но все они должны помещаться на одной строке и разделяться запятыми (если их несколько).

В теле макроопределения допустимы любые предложения языка ассемблера, в том числе и другие макродирективы. Допустимо любое число предложений. Каждый формальный параметр может быть использован любое число раз в этих предложениях.

Макроопределения могут быть вложенными, то есть, одно макроопределение может содержаться в другом. MASM не обрабатывает вложенные макроопределения до тех пор, пока не будет вызвано внешнее макроопределение. Поэтому вложенное макроопределение не может быть вызвано до тех пор, пока хотя бы один раз не было вызвано внешнее макроопределение. Глубина вложенности может быть произвольной и ограничивается лишь размером доступной при ассемблировании памяти.

Макроопределения могут содержать вызовы других макроопределений. Такие вложенные макровызовы обрабатываются так же, как и другие макровызовы, но лишь тогда, когда вызвано внешнее макроопределение.

Макроопределения могут быть рекурсивными, то есть, вызывать сами себя.

 

MASM ассемблирует предложения тела макроопределения только при макровызове и только в той точке исходного файла, где этот вызов имеет место. Таким образом, все адреса в ассемблируемом коде будут связаны с точкой макровызова, а не местоположением макроопределения. Макроопределение само по себе никогда не ассемблируется.

Следует соблюдать осторожность при использовании слова MACRO после директив TITLE, SUBTTL и NAME. Так как директива MACRO «перекрывает» эти директивы, использование такого слова после указанных директив приведет к тому, что Ассемблер начнет создавать макро с именами TITLE, SUBTTL или NAME. Например, предложение

TITLE Macro File

может быть внесено в исходный файл для создания заголовка «Macro File», но в результате будет создано макроопределение с именем TITLE, имеющее формальный параметр File, а, поскольку в этом случае, очевидно, не будет предусмотрена директива ENDM, закрывающая макроопределение, будет скорее всего генерироваться сообщение об ошибке.

Следует помнить, что MASM замещает все вхождения имени формального параметра в теле макроопределения его фактическим значением, даже если программисту это не нужно. Например, если формальный параметр имеет имя AX, в генерируемом макрорасширении MASM замещает все вхождения AX на значение фактического параметра. Если же по логике макроопределения необходимо использование регистра AX, а не одноименного формального параметра, код макрорасширения может быть некорректным.

Макроопределения могут быть переопределены. При этом можно не заботиться об удалении из исходного файла первого макроопределения, так как каждое следующее макроопределение автоматически замещает предыдущее макроопределение с тем же именем. Если переопределение совершается внутри самого макроопределения, необходимо помнить, что между директивами ENDM, закрывающими старое и новое макроопределения, не должно находиться никаких строк. Например, следующее переопределение некорректно:

dostuff MACRO

...

dostuf MACRO

...

ENDM

;; Ошибочная строка

ENDM

Макроопределение может быть вызвано в любой момент простым указанием его имени в исходном файле (имена макро в комментариях игнорируются). MASM при этом копирует предложения макроопределения в точку вызова, замещая в этих предложениях формальные параметры на фактические параметры, задаваемые при вызове.

Общий вид макровызова:

имя [[фактический-параметр,...]]

Имя должно быть именем ранее определенного в исходном файле макроопределения. Фактическим параметром может быть имя, число или другое значение. Допустимо любое число фактических параметров, но все они должны помещаться на одной строке. Элементы списка параметров должны разделяться запятыми, пробелами, или TAB-символами.

MASM замещает первый формальный параметр на первый фактический параметр, второй формальный параметр на второй фактический параметр. Если фактических параметров в макровызове больше, чем формальных параметров в макроопределении, лишние фактические параметры игнорируются. Если же фактических параметров меньше, чем формальных, формальные параметры, для которых не заданы фактические, замещаются пустыми строками (пробелами). Для определения того, заданы или не заданы соответствующие фактические параметры могут быть использованы директивы IFB, IFNB,.ERRB и.ERRNB.

В макросредствах языка Ассемблера имеется возможность передавать список значений в качестве одного параметра. Этот список должен быть заключен в одинарные скобки < и >, а сами элементы списка — разделяться запятыми. Пример:

allocb < 1, 2, 3, 4>

При написании макроопределений иногда возникает необходимость в задании меток инструкций или имен полей данных. Поскольку каждое макроопределение может использоваться многократно, может возникнуть ситуация, когда несколько имен или меток определены многократно, что вызовет ошибку трансляции. Для обеспечения правильной обработки таких ситуаций в макроязыке предусмотрена директива LOCAL, позволяющая локализовать заданные имена исключительно в данном макрорасширении.

Формат:

LOCAL формальное-имя,...

Формальное-имя может затем использоваться в данном макроопределении с уверенностью, что при каждом макровызове его значение будет уникальным. В директиве LOCAL, если она присутствует, должно быть задано хотя бы одно имя, а если их несколько, они должны разделяться запятыми.

Для обеспечения уникальности определенных директивой LOCAL имен MASM для каждого такого имени при каждом макровызове порождает реальное имя следующего вида:

?? номер

Номер представляет собой 16-ричное число в пределах от 0000 до FFFF. Для предотвращения повторного определения имен программисту не рекомендуется определять в своей программе имена этого типа.

Директива LOCAL может использоваться только в макроопределении, причем, там она должна предшествовать всем другим предложениям макроопределения, то есть, следовать непосредственно после MACRO.

Для удаления макроопределений служит директива PURGE.

Формат:

PURGE имя-макроопределения,...

Удаляются все текущие макроопределения с указанными именами. Последующий вызов одного из этих макроопределений будет приводить к ошибке.

Директива PURGE введена для возможности освобождения и повторного использования памяти, занимаемой неиспользуемыми в дальнейшем макроопределениями. Если имя-макроопределения представляет мнемонику инструкции или директивы, восстанавливается первоначальный смысл мнемоники в соответствии со значением данного ключевого слова.

Директива PURGE часто используется для удаления ненужных макроопределений из подключаемой директивой INCLUDE библиотеки макроопределений. Библиотека макроопределений представляет собой обычный последовательный файл, который в общем случае может содержать большое число макроопределений. Комбинация директив INCLUDE и PURGE позволяет выбрать из них только нужные для данной программы, что сократит размер исходного файла.

Нет необходимости удалять макроопределения после их переопределения, так как каждое переопределение автоматически удаляет предшествующее макроопределение с данным именем. Аналогично каждое макроопределение может удалить само себя, имея в своей последней обрабатываемой строке директиву PURGE.

 

Конец текущего макроопределения обозначается директивой ENDM, которая должна находиться в последней строке макроопределения.

Формат:

ENDM

Выход из текущего макроопределения до достижения директивы ENDM обеспечивается директивой EXITM, имеющей следующий формат:

EXITM

Выход из макроопределения по директивам ENDM и EXITM заключается в прекращении генерации текущего макрорасширения и возврате в точку вызова текущего макроопределения в динамически внешнем макрорасширении или в исходной программе.

Пример:

add MACRO param

IFB param

EXITM

ENDIF

ADD AX, param

ENDM

В этом мароопределении осуществляется добавление величины, определяемой формальным параметром param, к содержимому регистра AX. Блок условного ассемблирования IFB обеспечивает выход из макроопределения, если при вызове параметр не был задан.

Блоки повторений

Блок повторения представляет собой специфическую форму макроопределения с несколько ограниченными возможностями макроязыка. По сути блок повторения представляет собой макрообъект, объединяющий в себе макроопределение и макровызов. Макроопределения как шаблона, по которому производится генерация макрорасширения, здесь не требуется, в результате чего сужаются возможности варьирования генерируемым текстом. С другой стороны, использование блоков повторения по сравнению с макроопределениями является синтаксически и логически более простой задачей. Обработка блока повторения заключается в многократном дублировании тела блока с незначительными изменениями текста.

В языке Ассемблера имеются блоки повторения 3-х типов:

u REPT -блок;

u IRP -блок;

u IRPC -блок.

REPT -блок имеет следующий формат:

REPT выражение

...

предложения

...

ENDM

Блок предложений, заключенный между ключевыми словами REPT и ENDM, повторяется столько раз, каково текущее значение указанного выражения. Выражение должно иметь значение в виде 16-битового числа без знака и не может содержать внешних или неопределенных символов. Тело блока может включать в себя любые предложения языка.

IRP -блок имеет следующий формат:

IPR формальный-параметр, < параметр,...>

...

предложения

...

ENDM

Блок предложений, стоящий между ключевыми словами IRP и ENDM, будет повторен для каждого параметра в списке, заключенном в скобках < >.

Формальный-параметр относится только к данному блоку и последовательно принимает значения из списка. В качестве параметров в списке могут быть заданы определенные символы, строки, числа или символьные константы. Может быть задано любое число параметров, которые, если их несколько, должны разделяться запятыми. Тело блока может включать в себя любые предложения языка Ассемблера. Формальный-параметр в теле блока может быть использован произвольное число раз.

Когда MASM распознает директиву IRP, он создает копию предложений блока для каждого параметра в списке. При копировании предложений осуществляется замена текущим параметром всех вхождений формального параметра блока. Если в списке будет обнаружен пустой параметр ( < > ), формальный параметр получит значение пустой строки. Если список параметров пуст, блок игнорируется.

Пример:

alloc MACRO x

IRP y, < x>

DB y

ENDM

ENDM

В результате обработки макровызова

alloc < 0, 1, 2, 3>

будет сгенерировано макрорасширение

IRP y, < 0, 1, 2, 3>

DB y

ENDM

IRPC -блок имеет следующий формат:

IRPC формальный-параметр, строка

...

предложения

...

ENDM

Блок предложений, заключенный между ключевыми словами IRPC и ENDM, будет повторен для каждого символа указанной строки. При этом каждое вхождение формального параметра в блоке замещается текущим символом строки.

Строка представляет собой любую комбинацию букв, цифр и других символов. Если строка содержит пробелы, запятые или другие ограничители, она должна быть заключена в одинарные скобки < >.

Тело блока может включать в себя любые предложения языка Ассемблера. Формальный параметр в теле блока может быть использован произвольное число раз.

Когда MASM распознает директиву IRPC, он создает копию предложений блока для каждого символа в строке. При копировании предложений осуществляется замена текущим символом строки всех вхождений формального параметра блока.

 

 

Макрооператоры

В качестве элементов генерируемого текста в теле макроопределения могут быть использованы макрооператоры.

Оператор замены & обеспечивает замену в тексте формального параметра на значение соответствующего ему фактического параметра макроопределения. Символ & употребляется как перед, так и после имени формального параметра и служит для выделения параметра в строке символов или в строке, содержащей кавычки.

Во вложенных макроопределениях оператор замены может быть использован для задержки замены формального параметра действительным значением, для чего используется более общая форма оператора замены, в которой символ & может быть указан несколько раз. MASM трактует количество рядом стоящих символов & как глубину вложенности макроопределений (относительно текущего уровня), на которой следует осуществлять замену формального параметра.

Пример:

alloc MACRO x

IRP z, < 1, 2, 3> x& & z DB z

ENDM

ENDM

В этом примере замена формального параметра x осуществляется немедленно при вызове макроопределения. Замена параметра z будет задержана до начала обработки блока повторения IRP с тем, чтобы параметр z получал значения из указанного списка. Таким образом, параметр z будет замещаться значением элемента списка каждый раз при переходе к следующему элементу списка блока повторения. В итоге по макрокоманде

alloc var

будет сгенерировано макрорасширение

var1 DB 1

var2 DB 2

var3 DB 3

Текстовый оператор литерала указывает MASM, что заданный внутри скобок < и > текст следует трактовать как простой литеральный элемент независимо от того, содержит ли он запятые, пробелы или другие ограничители. Чаще всего этот оператор используется в макровызовах и директивах IRP для того, чтобы значения списка параметров обрабатывались как один параметр.

Кроме того, этот оператор используется в тех случаях, когда необходимо, чтобы MASM трактовал некоторые специальные символы (например,; или & ) как литералы. Например, в выражении <; > точка с запятой рассматривается как точка с запятой, а не как начало комментария.

Символьный оператор литерала! отличается от текстового лишь тем, что в нем в качестве литерала рассматривается только непосредственно следующий за! символ. Например, выражения!; и <; > эквивалентны.

Оператор выражения % указывает MASM, что данный текст следует трактовать как выражение. MASM вычисляет значение выражения с учетом основания системы счисления встречающихся в выражении чисел и замещает текст этим значением. Текст должен представлять корректное выражение.

Оператор выражения обычно используется в макровызовах, когда в макроопределение необходимо передать значение выражения, а не его текстовую форму.

Пример:

area MACRO par

DW & par

ENDM

sum1 EQU 100

sum2 EQU 200

В результате обработки макровызова

area %(sum1+sum2)

будет сгенерировано макрорасширение

DW 300

Оператор макрокомментария;; определяет, что остаток строки является макрокомментарием.

В отличие от обычного комментария, который обозначается одинарными точкой с запятой и также может встречаться в макроопределениях, макрокомментарий в текст макрорасширения не попадает. Он присутствует лишь в теле макроопределения.

 

Директивы определения памяти

Директивы определения памяти служат для задания размеров, содержимого и местоположения полей данных, используемых в программе на языке Ассемблера. В отличие от других директив языка Ассемблера при обработке директив определения памяти генерируется объектный код. MASM транслирует задаваемые в директивах определения памяти числа, строки и выражения в отдельные образы байтов, слов или других единиц данных. Эти образы копируются в объектный файл.

Директивы определения данных могут задавать:

u Скалярные данные, представляющие собой единичное значение или набор единичных значений.

u Записи, позволяющие манипулировать с данными на уровне бит.

u Структуры, отражающие некоторую логическую структуру данных.

Скалярные данные

Директива DB обеспечивает распределение и инициализацию 1 байта памяти для каждого из указанных значений. В качестве значения может кодироваться целое число, строковая константа, оператор DUP, абсолютное выражение или знак?. Знак? обозначает неопределенное значение. Значения, если их несколько, должны разделяться запятыми.

Если директива имеет имя, создается переменная типа BYTE с соответствующим данному значению указателя позиции смещением.

Строковая константа может содержать столько символов, сколько помещается на одной строке.

 

Символы строки хранятся в памяти в порядке их следования, то есть, 1-й символ имеет самый младший адрес, последний — самый старший.

Директива DW обеспечивает распределение и инициализацию слова памяти (2 байта) для каждого из указанных значений. В качестве значения может кодироваться целое число, 1- или 2-х символьная константа, оператор DUP, абсолютное выражение, адресное выражение или знак?. Знак? обозначает неопределенное значение. Значения, если их несколько, должны разделяться запятыми.

Если директива имеет имя, создается переменная типа WORD с соответствующим данному значению указателя позиции смещением.

Строковая константа не может содержать более 2-х символов. Последний (или единственный) символ строки хранится в младшем байте слова. Старший байт содержит первый символ или, если строка односимвольная, 0.

Директива DD обеспечивает распределение и инициализацию двойного слова памяти (4 байта) для каждого из указанных значений. В качестве значения может кодироваться целое число, 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-ричных).

Если в одной директиве определения памяти заданы несколько значений, им распределяются последовательные байты памяти.

Во всех директивах определения памяти в качестве одного из значений может быть задан оператор 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

charu DQ 'b'

encodeu DQ 3F00000000000000r

highu 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)

Записи

Запись представляет собой набор полей бит, объединенных одним именем. Каждое поле записи имеет собственную длину, исчисляемую в битах, и не обязана занимать целое число байтов.

Объявление записи в программе на языке Ассемблера включает в себя 2 действия:

1. Объявление шаблона или типа записи директивой RECORD.

2. Объявление собственно записи.

Формат директивы RECORD:

имя-записи RECORD

имя-поля: длина[[=выражение]],...

Директива RECORD определяет вид 8- или 16-битовой записи, содержащей одно или несколько полей.

Имя-записи представляет собой имя типа записи, которое будет использоваться при объявлении записи. Имя-поля и длина (в битах) описывают конкретное поле записи. Выражение, если оно указано задает начальное (умалчиваемое) значение поля.

Описания полей записи в директиве RECORD, если их несколько, должны разделяться запятыми. Для одной записи может быть задано любое число полей, но их суммарная длина не должна превышать 16 бит.

Длина каждого поля задается константой в пределах от 1 до 16. Если общая длина полей превышает 8 бит, Ассемблер выделяет под запись 2 байта, в противном случае — 1 байт.

Если задано выражение, оно определяет начальное значение поля. Если длина поля не меньше 7 бит, в качестве выражения может быть использован символ в коде ASCII. Выражение не должно содержать ссылок вперед.

Внутри записи поля размещаются слева направо в порядке описания в директиве RECORD. Поэтому объявленное первым поле содержит самые значимые биты записи, если рассматривать ее как двоичное число. Если суммарная длина полей не равна 8 или 16, запись расширяется до целой границы байта нулевыми битами слева, и, таким образом, последний бит последнего поля всегда является самым младшим битом записи.

При обработке директивы RECORD формируется шаблон записи, а сами данные создаются при объявлении записи, которое имеет следующий вид:

[[имя]] имя-записи < [[значение,...]]>

По такому объявлению создается переменная типа записи с 8- или 16-битовым значением и структурой полей, соответствующей шаблону, заданному директивой RECORD с именем имя-записи.

Имя задает имя переменной типа записи. Если имя опущено, MASM распределяет память, но не создает переменную, которую можно было бы использовать для доступа к записи.

В скобках < > указывается список значений полей записи. Значения в списке, если их несколько, должны разделяться запятыми. Каждое значение может быть целым числом, строковой константой или выражением и должно соответствовать длине данного поля. Для каждого поля может быть задано одно значение.

Скобки < > обязательны, даже если начальные значения не заданы.

Если в качестве значения используется оператор DUP, в скобки < > следует заключать список значений оператора DUP. Следует иметь ввиду, что при использовании оператора DUP создается несколько переменных типа запись.

Задавать значения всех полей записи необязательно. Если Ассемблер вместо значения обнаружит левый пробел, будет использовано начальное значение поля, заданное директивой RECORD, а если оно и там опущено, значение поля будет не определено.

Структуры

Структура представляет собой набор полей байтов, объединенных одним именем.

Объявление структуры в программе на языке Ассемблера включает в себя 2 действия:

1. Объявление шаблона или типа структуры директивами STRUC и ENDS.

2. Объявление собственно структуры.

Формат объявления типа структуры:

имя STRUC

описания-полей

имя ENDS

Директивы STRUC и ENDS обозначают соответственно начало и конец описания шаблона (типа) структуры. Описание типа структуры задает имя типа структуры и число, типы и начальные значения полей структуры.

Указанное в директивах STRUC и ENDS имя задает новое имя типа структуры. Оно должно быть уникальным. Описания-полей определяют поля структуры и могут быть заданы в одной из следующих форм:

[[имя]] DB значение,...

[[имя]] DW значение,...

[[имя]] DD значение,...

[[имя]] DQ значение,...

[[имя]] DT значение,...

 

Каждое поле может иметь свое имя. Директивы DB, DW, DD, DQ или DT задают длину поля. Для каждого поля могут быть указаны начальные значения, которыми инициализируются поля при отсутствии соответствующих начальных значений при объявлении структуры. Имя каждой директивы, если оно задано, должно быть уникальным и представляет смещение поля относительно начала структуры.


Поделиться:



Популярное:

Последнее изменение этой страницы: 2017-03-08; Просмотров: 1501; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.153 с.)
Главная | Случайная страница | Обратная связь