<?xml version="1.0" encoding="windows-1251"?>
<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:l="http://www.w3.org/1999/xlink">
 <description>
  <title-info>
   <genre>comp_programming</genre>
   <author>
    <first-name>Tomasz</first-name>
    <last-name>Grysztar</last-name>
   </author>
   <book-title>Flat Assembler 1.64. Мануал программера</book-title>
   <date></date>
   <coverpage>
    <image l:href="#cover.png"/></coverpage>
   <lang>ru</lang>
   <src-lang>en</src-lang>
   <translator>
    <nickname>Paranoik</nickname>
   </translator>
  </title-info>
  <document-info>
   <author>
    <nickname>Stribog</nickname>
   </author>
   <program-used>FictionBook Editor Release 2.6.6</program-used>
   <date value="2013-07-31">31 July 2013</date>
   <id>22852B62-A312-4005-A986-D866151B0010</id>
   <version>1.0</version>
  </document-info>
 </description>
 <body>
  <title>
   <p><strong>FLAT ASSEMBLER 1.64</strong></p>
   <p><strong>Мануал программера</strong></p>
  </title>
  <section>
   <title>
    <p>Глава 1. Введение</p>
   </title>
   <section>
    <p>Эта глава содержит всю важнейшую информацию, которая понадобится вам, чтобы начать использовать flat assembler. Если у вас уже есть опыт программирования на ассемблере, вам достаточно прочитать лишь первую главу перед использованием этого компилятора.</p>
   </section>
   <section>
    <title>
     <p>1.1 Обзор компилятора</p>
    </title>
    <section>
     <p>Flat assembler — это быстрый компилятор ассемблера для процессоров с архитектурой х86, который делает множественные проходы для оптимизации размера сгенерированного машинного кода. Он способен скомпилировать сам себя и существуют версии для разных операционных систем. Все версии созданы для использования с помощью системной командной строки и в обращении с ними нет разницы.</p>
    </section>
    <section>
     <title>
      <p>1.1.1 Системные требования</p>
     </title>
     <p>Для работы всех версий требуется 32-битный процессор с архитектурой х86 (как минимум 80386), хотя также он должен обрабатывать программы для 16-битных процессоров с архитектурой х86. DOS-версия требует ОС, совместимую с MS DOS 2.0, Windows-версия требует консоль Win32, совместимую с версией 3.1.</p>
    </section>
    <section>
     <title>
      <p>1.1.2 Работа с компилятором из командной строки</p>
     </title>
     <p>Для запуска FASMа из командной строки вам понадобится ввести два параметра: первый — это путь к файлу с кодом, второй — путь к файлу-адресату информации. Если второй параметр не задан, название файла вывода будет создано автоматически. После показа короткой информации о названии программы и её версии, компилятор считает информацию из файла с кодом и скомпилирует её. После успешной компиляции FASM запишет сгенерированный код в файл-адресат и выведет краткую информацию о завершенном процессе; в противном случае он выведет информацию о первой ошибке.</p>
     <p>Исходник должен быть текстовым файлом и может быть создан в любом текстовом редакторе. Обрыв строки допускается и в стандарте DOS, и в стандарте Unix, табуляции обрабатываются как пробелы.</p>
     <p>В командную строку вы также можете включить опцию «<code>-m</code>», за которой должно следовать число, указывающее, сколько килобайт памяти может быть максимально задействовано flat assembler'ом. В случае DOS-версии эта опция ограничивает лишь использование расширенной памяти. Опция «<code>-p</code>» со следующим за ним числом может быть использована для того, чтобы ограничить количество проходов, которое будет делать ассемблер. Если код не может быть создан заданным числом проходов, ассемблирование прекратится с сообщением об ошибке. Максимальное значение этой опции равно 65536, а значение по умолчанию равно 100.</p>
     <p>Не существует опций, оказывающих воздействие на выходные данные компилятора, вся необходимая flat assembler'у информация должна содержаться в исходном коде. Например, для установки формата файла-адресата используется директива «<code>format</code>» в начале кода.</p>
    </section>
    <section>
     <title>
      <p>1.1.3 Сообщения компилятора</p>
     </title>
     <p>Как было сказано выше, после успешной компиляции FASM выводит на экран сводку о проделанной работе. Она включает информацию о том, сколько было сделано проходов, сколько времени это заняло, и сколько байт записано в файл-адресат.</p>
     <p>Вот пример такой сводки:</p>
     <p><code>flat assembler version 1.64</code></p>
     <p><code>38 passes, 5.3 seconds, 77824 bytes.</code></p>
     <p>В случае ошибки во время компиляции, программа выведет на экран сообщение об ошибке. Например, когда компилятор не может найти файл ввода, он покажет следующее сообщение:</p>
     <p><code>flat assembler version 1.64</code></p>
     <p><code>error: source file not found.</code></p>
     <p>Если ошибка связана с определенной частью кода, будет выведена строка, которая её вызвала. Также, чтобы помочь вам найти эту ошибку, будет показано место этой строки в коде, например:</p>
     <p><code>flat assembler version 1.64</code></p>
     <p><code>example.asm [3]:</code></p>
     <p><code>mob ax,1</code></p>
     <p><code>error: illegal instruction.</code></p>
     <p>Это значит, что в третьей строке файла «<code>example.asm</code>» компилятор встретил неопознанную инструкцию. Если строка, вызвавшая ошибку, содержит макрос, также будет выведена строка в формулировке макроса, которая сгенерировала ошибочную инструкцию:</p>
     <p><code>flat assembler version 1.64</code></p>
     <p><code>example.asm [6]:</code></p>
     <p><code>stoschar 7</code></p>
     <p><code>example.asm [3] stoschar [1]:</code></p>
     <p><code>mob al,char</code></p>
     <p><code>error: illegal instruction.</code></p>
     <p>Это значит, что макрос в шестой строке файла «<code>example.asm</code>» создал неопознанную инструкцию в первой строке своей формулировки.</p>
    </section>
    <section>
     <title>
      <p>1.1.4 Форматы вывода</p>
     </title>
     <p>По умолчанию, если в исходнике нет директивы «<code>format</code>», flat assembler направляет сгенерированный код на вывод, создавая таким образом простой двоичный файл. По умолчанию он создает 16-битный код, но вы всегда можете переключить его в 32-битный или 16-битный режим, используя директивы «<code>use32</code>» или «<code>use16</code>». Выбор некоторых форматов файла-адресата автоматически переключает компилятор в 32-битный режим. Подробнее читайте о форматах, которые можете выбрать, в 2.4.</p>
     <p>Весь сгенерированный код в файле-адресате всегда идет в том же порядке, что и написанный в исходнике.</p>
    </section>
   </section>
   <section>
    <title>
     <p>1.2 Синтаксис ассемблера</p>
    </title>
    <section>
     <p>Информация, изложенная ниже, предназначена главным образом программистам, которые прежде использовали другие компиляторы ассемблера. Если вы новичок, читайте учебники по программированию на ассемблере.</p>
     <p>Flat assembler по умолчанию использует Интеловский синтаксис ассемблерных инструкций, однако вы можете переделать их, используя возможности препроцессора (макросы и символьные константы). Он также имеет собственный набор директив — инструкций для компилятора.</p>
     <p>Все символы, определенные внутри кода, чувствительны к регистру.</p>
    </section>
    <section>
     <title>
      <p>1.2.1 Синтаксис инструкций</p>
     </title>
     <p>Инструкции в ассемблере разделяются разрывами строк, и одна инструкция должна располагаться на одной строке. Если строка содержит точку с запятой, не считая точек с запятой, заключенных в кавычки, остаток её считается комментарием и компилятор её проигнорирует. Если строка содержит символ «<code>\</code>» (в конце концов точка с запятой и комментарий могут за ней следовать), то следующая срока прикрепляется к этой точке. После символа «<code>\</code>» строка не должна содержать ничего, кроме комментариев, следующих за точкой с запятой.</p>
     <p>Каждая строка в коде — это последовательность отдельных предметов, каждый из которых может принадлежать к одному из трек типов. Первый тип — это знаки символов, которыми являются специальные знаки, которые трактуются отдельно, даже если не отделены пробелами о других символов. Любой из <code>«+-*/=&lt;&gt;()[]{}:,|&amp;~#`</code>» — это знак символа. Последовательность других знаков, отделенная от остальных либо пробелами, либо знаками символов, это символ. Если первый знак такого символа двойная либо одинарная кавычка, он объединяет любую последовательность символов, даже специальных, следующих за ним, в строку. Она должна заканчиваться таким же знаком, каким начиналась (двойной либо одинарной кавычкой). Однако если встречаются две кавычки подряд (без знаков между ними), они также включаются в строку и она продолжается. Символы, отличные от знаков символов и строк, заключенных в кавычки, могут использоваться как имена, поэтому они также называются символами имен.</p>
     <empty-line/>
     <subtitle><sup><strong>Таблица 1.1</strong> <emphasis>Размеры операторов</emphasis></sup></subtitle>
     <image l:href="#i_001.png"/>
     <empty-line/>
     <p>Каждая инструкция состоит из мнемоника и различного числа операндов, разделенных запятыми. Операндом может быть регистр, непосредственное значение или адрес в памяти, он также может предварен оператором размера, чтобы определить или изменить его размер (таблица 1.1). Названия возможных регистров вы можете найти в таблице 1.2, их размеры не могут быть изменены. Непосредственные значения могут быть определены любым числовым значением.</p>
     <empty-line/>
     <subtitle><sup><strong>Таблица 1.2</strong> <emphasis>Регистры</emphasis></sup></subtitle>
     <image l:href="#i_002.png"/>
     <empty-line/>
     <p>Если операнд — это данные в памяти, адрес этих данных (также любого числового выражения, но оно может содержать регистры) должен быть заключен в квадратные скобки или предварен оператором «<code>ptr</code>». Например, инструкция «<code>mov eax,3</code>» поместит число 3 в регистр EAX, а инструкция «<code>mov eax,[7]</code>» поместит 32-битное значение из адреса 7 в EAX, и инструкция «<code>mov byte [7],3</code>» поместит число 3 в байт по адресу 7, это можно записать еще так: «<code>mov byte ptr 7,3</code>». Для того, чтобы установить, какой сегментный регистр будет использоваться для адресации, нужно поставить его название с двоеточием перед адресом внутри квадратных скобок или после оператора «<code>ptr</code>».</p>
    </section>
    <section>
     <title>
      <p>1.2.2 Описание данных</p>
     </title>
     <p>Чтобы описать данные или зарезервировать для них место, используйте одну из директив, перечисленных в таблице 1.3. За директивой описания данных должно следовать одно или несколько числовых значений, разделенных запятыми. Эти выражения определяют значения для простейших элементов данных, размер которых зависит от того, какая директива используется. Например «<code>db 1,2,3</code>» описывает три байта со значениями 1, 2 и 3 соответственно.</p>
     <empty-line/>
     <subtitle><sup><strong>Таблица 1.3</strong> <emphasis>Директивы данных</emphasis></sup></subtitle>
     <image l:href="#i_003.png"/>
     <empty-line/>
     <p>Директивы «<code>du</code>» и «<code>db</code>» также поддерживают сроки любой длины, заключенные в кавычки, которые будут конвертированы в последовательность байтов, если использована директива «<code>db</code>», или в последовательность слов с нулевым верхним байтом, если использована директива «<code>du</code>». Например, «<code>db 'abc'</code>» определяет три байта со значениями 61, 62 и 63.</p>
     <p>Директива «<code>dp</code>» или её синоним «<code>df</code>» допускают, чтобы значения состояли из двух числовых выражений, разделенных двоеточием, где первое значение — это верхнее слово, а второе — это нижнее двойное слово значения дальнего указателя. Также «<code>dd</code>» допускает такие указатели, состоящие из двух слов, разделенных двоеточием, и «<code>dt</code>» допускает слово и четверное слово, разделенные двоеточием, четверное слово запоминается первым. Директива «<code>dt</code>» с одним параметром допускает только значения с плавающей точкой и создает данные в FPU-формате двойной расширенной точности.</p>
     <p>Все вышеперечисленные директивы поддерживают использование специального оператора «<code>dup</code>» для создания копий данных значений. Количество дубликатов должно стоять перед этим оператором, а их значение должно стоять после — это может быть даже цепь значений, разделенных запятыми, но эта цепь должна быть заключена в скобки, например «<code>db 5 dup (1,2)</code>» определяет пять копий данной последовательности из двух байтов.</p>
     <p>«<code>file</code>» — это специальная директива и её синтаксис может быть различным. Эта директива включает цепь байтов из файла. В качестве параметра за ней должно идти в кавычках имя файла, далее, опционально, двоеточие и числовое выражение, указывающее начало цепочки байтов, далее, также опционально, запятая и числовое выражение, определяющее количество байтов в этой цепочке (если этот параметр не определен, то будут включены все данные до конца файла). Например, «<code>file 'data.bin'</code>» включит весь файл как двоичные данные, а «<code>file 'data.bin':10h,4</code>» включит только четыре байта, начиная со смещения 10h.</p>
     <p>За директивой резервирования данных должно следовать одно числовое выражение, значение которого определяет количество резервируемых ячеек установленного размера. Все директивы описания данных также поддерживают значение «<code>?</code>», которое значит, что этой ячейке не должно быть присвоено какое-то значение. Эффект от этой директивы такой же, как от директивы резервирования данных. Неинициализированные данные не могут быть включены в файл вывода, и, таким образом, их значения всегда будут считаться неизвестными.</p>
    </section>
    <section>
     <title>
      <p>1.2.3 Константы и метки</p>
     </title>
     <p>В числовых выражениях вместо чисел вы также можете использовать константы и метки. Чтобы назначить их, используйте специальные директивы. Каждая метка может быть определена только однажды и она будет доступна из любой части кода (даже перед местом, где она была определена). Константа может быть переопределена много раз, но в этом случае она будет доступна только после присвоения значения и всегда будет равна значению из последнего определения перед местом, в котором она использована. Если константа определена лишь однажды, она, так же как и метка, доступна из любой части кода.</p>
     <p>Определение константы состоит из имени константы, знака «<code>=</code>» и числового выражения, которое после вычисления становится значением константы. Это значение всегда вычисляется в то же время, что и определение константы. Например, с помощью директивы «<code>count = 17</code>» вы можете определить константу «<code>count</code>» и после использовать её в инструкциях ассемблера, таких как «<code>mov cx,count</code>» — которая превратится в «<code>mov cx,17</code>» во время процесса компиляции.</p>
     <p>Существуют разные способы определения меток. Простейший из них — двоеточие после названия метки. За этой директивой на той же строке даже может следовать другая инструкция. Она определяет метку, значение которой равно смещению точки, в которой она определена. Этот метод обычно используется, чтобы пометить места в коде. Другой способ — это следование за именем метки (без двоеточия) какой-нибудь директивы описания данных. Метке присваивается значение адреса начала определенных в директиве данных и запоминается компилятором как метка для данных с размером ячейки, заданной директивой из таблицы 1.3.</p>
     <p>Метка может быть обработана как константа со значением, равным смещению помеченного кода или данных. Например, если вы определяете данные, используя помеченную директиву «<code>char db 224</code>», для того, чтобы поместить адрес начала этих данных в регистр BX, вам нужно использовать инструкцию «<code>mov bx,char</code>», а для того, чтобы поместить в регистр DL значение байта, на который ссылается «<code>char</code>», нужно использовать «<code>mov dl,[char]</code>» (или «<code>mov dl,ptr char</code>»). Если вы попытаетесь ассемблировать «<code>mov ax,[char]</code>», FASM выдаст ошибку, так как он сравнивает размеры операндов, которые должны быть равны. Вы можете принудительно проассемблировать эту инструкцию, изменяя размер операнда: «<code>mov ax, word [char]</code>», но помните, что эта инструкция прочитает два байта, начинающихся с адреса «<code>char</code>», тогда как он был определен как один байт.</p>
     <p>Последний и самый гибкий способ задания меток — это использование директивы «<code>label</code>». За этой директивой должно следовать имя метки, далее, опционально, размер оператора (может предваряться двоеточием), и далее, также опционально, оператор «<code>at</code>» и числовое выражение, определяющее адрес, на который данная метка должна ссылаться. Например, «<code>label wchar word at char</code>» определяет новую метку для 16-битных данных по адресу «<code>char</code>». Теперь инструкция «<code>mov ax,[wchar]</code>» после компиляции будет выглядеть так же, как «<code>mov ax,word [char]</code>». Если адрес не указан, директива «<code>label</code>» будет ссылаться на текущий адрес. Таким образом, «<code>mov [wchar],57568</code>» скопирует два байта, тогда как «<code>mov [char],224</code>» скопирует один байт на тот же адрес.</p>
     <p>Метка, имя которой начинается с точки, обрабатывается как локальная, и её имя прикрепляется к имени последней глобальной метки (с названием, начинающемся с чего угодно, кроме точки) для создания полного имени этой метки. Так, вы можете использовать короткое имя (начинающееся с точки) где угодно перед следующей глобальной меткой, а в других местах вам придется пользоваться полным именем. Метки, начинающиеся с двух точек — исключения. Они имеют свойства глобальных, но не создают новый префикс для локальных меток.</p>
     <p>«<code>@@</code>» обозначает анонимную метку, вы можете определить её множество раз. Символ «<code>@b</code>» (или эквивалент «<code>@r</code>») ссылается на ближайшую предшествующую анонимную метку, а символ «<code>@f</code>» ссылается на ближайшую после неё анонимною метку. Эти специальные символы нечувствительны к регистру.</p>
    </section>
    <section>
     <title>
      <p>1.2.4 Числовые выражения</p>
     </title>
     <p>В предыдущих примерах все числовые выражения были обычными числами, константами или метками. Но они могут быть более сложными, использовать арифметические или логические операторы для вычисления во время компиляции. Все эти операторы с их значениями приоритета перечислены в таблице 1.4.</p>
     <empty-line/>
     <subtitle><sup><strong>Таблица 1.4</strong> <emphasis>Арифметические и логические операторы в порядке приоритета</emphasis></sup></subtitle>
     <image l:href="#i_004.png"/>
     <empty-line/>
     <p>Операции с высшим приоритетом выполняются первыми, однако вы, конечно, можете изменить такой образ действий, заключив некоторые части выражения в скобочки. «<code>+</code>», «<code>-</code>", «<code>*</code>» и «<code>/</code>» — это стандартные арифметические операции, «<code>mod</code>» вычисляет остаток от деления нацело. «<code>and</code>», «<code>or</code>», «<code>xor</code>», «<code>shl</code>», «<code>shr</code>» и «<code>not</code>» совершают те же логические операции, что и инструкции ассемблера с такими же названиями. «<code>rva</code>» характерна только для формата вывода PE и производит превращение адреса в RVA.</p>
     <p>Числа в выражениях по умолчанию обрабатываются как десятичные, двоичные числа должны иметь «<code>b</code>» в конце, восьмеричные числа должны заканчиваться на букву «<code>o</code>», шестнадцатеричные цифры должны начинаться символами «<code>0x</code>» (как в языке C), или символом «<code>$</code>» (как в языке Pascal) или должны заканчиваться буквой «<code>h</code>». Также заключенная в кавычки строка при включении в выражение будет конвертирована в число — первый символ станет минимальным значащим байтом числа. Числовые выражения, используемые как значения адреса, могут также содержать любой из общих регистров, используемых для адресации, они могут быть сложены или умножены на подходящие значения так, как это позволено в инструкциях архитектуры x86.</p>
     <p>Также есть несколько специальных символов, которые могут быть использованы в числовом выражении. Первое — это «<code>$</code>», которое всегда равно значению текущего смещения, тогда как «<code>$$</code>» равно базовому адресу текущего диапазона адресов. Следующий символ — «<code>%</code>» — это номер текущего повтора в частях кода, которые повторяются, благодаря использованию некоторых специальных директив (смотрите 2.2). Также существует символ «<code>%t</code>», который всегда равен текущей отметке времени.</p>
     <p>Любое численное выражение также может состоять из одного значения с плавающей точкой (flat assembler не может производить во время компиляции операции с плавающей точкой) в научной записи. Для распознания компилятором, эти значения должны содержать в конце букву «<code>f</code>», либо включать в себя по крайней мере один символ "<code>.</code>» или «<code>E</code>». Так, «<code>1.0</code>», «<code>1E0</code>» и «<code>1f</code>» определяют одно и то же значение с плавающей точкой, когда как просто «<code>1</code>» определяет целочисленное значение.</p>
    </section>
    <section>
     <title>
      <p>1.2.5 Переходы и вызовы</p>
     </title>
     <p>Операнд любого перехода или инструкция вызова может предваряться не только операторами размера, но также одним из операторов, определяющих тип перехода: «<code>near</code>» или «<code>far</code>». Например, если ассемблер в 16-битном режиме, инструкция «<code>jmp dword [0]</code>» станет далеким переходом, а если ассемблер в 32-битном режиме, она станет близким переходом. Чтобы заставить эту инструкцию обрабатываться по-разному, используйте формы «<code>jmp near dword [0]</code>» или «<code>jmp far dword [0]</code>».</p>
     <p>Если операнд близкого перехода это немедленное значение, ассемблер, если возможно, сгенерирует кратчайший вариант этой инструкции перехода (но не будет создавать 32-битную инструкцию в 16-битном режиме или 16-битную инструкцию в 32-битном режиме, если оператор размера точно её не определит). Заданием оператора размера вы можете заставить ассемблер всегда генерировать длинный вариант (например, «<code>jmp word 0</code>» в 16-битном режиме или «<code>jmp dword 0</code>» в 32-битном режиме) или всегда создавать короткий вариант и завершаться с ошибкой, когда это невозможно (например «<code>jmp byte 0</code>»).</p>
    </section>
    <section>
     <title>
      <p>1.2.6 Установки размера</p>
     </title>
     <p>Если инструкция использует некоторую адресацию в памяти, по умолчанию будет генерироваться кратчайшая 8-битная форма, если значение адреса попадает в нужный диапазон, но он может быть изменен с помощью операторов «<code>word</code>» и «<code>dword</code>» перед адресом в квадратных скобках (или после оператора «<code>ptr</code>»). Такое размещение оператора размера также может быть использовано для установки размера адреса, отличного от размера, установленного в данном режиме по умолчанию.</p>
     <p>Инструкции «<code>adc</code>», «<code>add</code>», «<code>and</code>», «<code>cmp</code>», «<code>or</code>», «<code>sbb</code>», «<code>sub</code>» и «<code>xor</code>» с первым 16-ти или 32-битным операндом по умолчанию генерируются в укороченной 8-битной форме, если второй операнд — это непосредственное значение, применимое для предписанных 8-битных значений. Она также может быть изменена операторами «<code>word</code>» и «<code>dword</code>» перед такими значениями. Сходные правила применимы к инструкции «<code>imul</code>» с непосредственным значениям в качестве последнего операнда.</p>
     <p>Непосредственное значение как операнд для инструкции «push» без оператора размера, по умолчанию обрабатывается как слово, если ассемблер 16-битном режиме, и как двойное слово, если FASM в 32-битном режиме. Короткая 8-битная форма используется по возможности, операторы размера «<code>word</code>» и «<code>dword</code>» могут заставить инструкцию «<code>push</code>» быть сгенерированной в более длинной форме. Мнемоники «<code>pushw</code>» и «<code>pushd</code>» указывают ассемблеру сгенерировать 16-битный или 32-битный код без принуждения его использовать длинную форму инструкции.</p>
    </section>
   </section>
  </section>
  <section>
   <title>
    <p>Глава 2. Описание инструкций</p>
   </title>
   <section>
    <p>Эта глава содержит детальную информацию об инструкциях и директивах, поддерживаемых FASMом. Директивы определения констант и меток уже описаны в 1.2.3, все остальные директивы будут описаны ниже в этой главе.</p>
   </section>
   <section>
    <title>
     <p>2.2 Директивы управления</p>
    </title>
    <section>
     <p>Этот параграф описывает директивы, которые управляют процессом ассемблирования. Эти директивы выполняются во время ассемблирования и могут делать так, чтобы некоторые блоки инструкций ассемблировались по-разному или не ассемблировались вовсе.</p>
    </section>
    <section>
     <title>
      <p>2.2.1 Условное ассемблирование</p>
     </title>
     <p>С помощью директивы «<code>if</code>» можно ассемблировать или не ассемблировать блок инструкций в зависимости от выполнения условия. За ней должно следовать логическое выражение, определяющее условие. Инструкции на следующих строках ассемблируются, только если это условие выполняется, иначе они пропускаются. Опциональная директива «<code>elseif</code>» со следующим за ней логическим выражением, определяющим дополнительное условие, начинает следующий блок инструкций, который ассемблируется, если предыдущие условия не выполняются, а данное дополнительное условие выполняется. Опциональная директива «<code>else</code>» начинает блок инструкций, которые ассемблируются, если не выполняется ни одно из условий. «<code>end if</code>» заканчивает последний блок инструкций.</p>
     <p>Вы должны помнить, что директива «<code>if</code>» обрабатывается на стадии ассемблирования и поэтому не влияет на директивы препроцессора, такие как определения символьных констант и макроинструкции — когда ассемблер распознает директиву «<code>if</code>», весь препроцессинг уже закончен.</p>
     <p>Логическое выражение состоит из логических значений и логических операторов. Логические операторы выглядят так: «<code>~</code>» для логического отрицания, «<code>&amp;</code>» для логического И, «<code>|</code>» для логического ИЛИ. Отрицание имеет высший приоритет. Логическое значение может быть числовым выражением, оно будет считаться ложным в случае равенства нулю, иначе оно будет истинным. Для создания логического значения можно сравнить два числовых выражения, используя один из следующих операторов: «<code>=</code>» (равно), «<code>&lt;</code>» (меньше), «<code>&gt;</code>» (больше), «<code>&lt;=</code>» (меньше или равно), «<code>&gt;=</code>» (больше или равно), «<code>&lt;&gt;</code>» (не равно).</p>
     <p>«<code>used</code>» со следующим за ним символом имени, это логическое значение, которое проверяет, использовался ли где-нибудь данный символ (он возвращает правильный результат даже если символ используется только после этой проверки). За оператором «<code>defined</code>» может следовать любое выражение, обычно это только одно символьное имя; этот оператор проверяет, содержит ли данное выражение исключительно символы, определенные в коде, и доступные из текущей позиции.</p>
     <p>Следующий простой пример использует константу «<code>count</code>» которая должна быть определена где-то в коде:</p>
     <p><code>if count&gt;0</code></p>
     <p><code> mov cx,count</code></p>
     <p><code> rep movsb</code></p>
     <p><code>end if</code></p>
     <p>Эти две инструкции будут ассемблированы только если константа «<code>count</code>» больше нуля. Следующий пример показывает более комплексную условную структуру:</p>
     <p><code>if count &amp; ~ count mod 4</code></p>
     <p><code> mov cx,count/4</code></p>
     <p><code> rep movsd</code></p>
     <p><code>else if count&gt;4</code></p>
     <p><code> mov cx,count/4</code></p>
     <p><code> rep movsd</code></p>
     <p><code> mov cx,count mod 4</code></p>
     <p><code> rep movsb</code></p>
     <p><code>else</code></p>
     <p><code> mov cx,count</code></p>
     <p><code> rep movsb</code></p>
     <p><code>end if</code></p>
     <p>Первый блок инструкций ассеблируется, если константа «count» не равна нулю и кратна четырем, если это условие не выполняется, оценивается второе логическое условие, следующее за «<code>else if</code>», и если оно верно, ассемблируется второй блок инструкций, иначе ассемблируется последний блок, который следует за строкой, содержащей только «<code>else</code>».</p>
     <p>Также есть операторы, которые позволяют сравнивать значения, которые представляют собой последовательности символов. «<code>eq</code>» проверяет такие значения на тождественность. Оператор «<code>in</code>» проверяет, принадлежит ли данное значение к списку значений, следующему за оператором. Список должен быть заключен между символами «<code>&lt;</code>» и «<code>&gt;</code>», а его члены должны быть разделены запятыми. Символы считаются одинаковыми, если они имеют одно и то же значение для ассемблера — например, «<code>pword</code>» и «<code>fword</code>» для ассемблера одинаковы поэтому не различаются вышеуказанными операторами. Так же «<code>16 eq 10h</code>» является истиной, однако «<code>16 eq 10+4</code>» нет.</p>
     <p>Оператор «<code>eqtype</code>» имеют ли сравниваемые значения одинаковую структуру, и принадлежат ли структурные элементы одному типу. Различаемые типы включают в себя числовые выражения, строки, заключенные в кавычки, значения с плавающей точкой, адресные выражения (выражения в квадратных скобках или предваренные оператором «<code>ptr</code>»), мнемоники инструкций, регистры, операторы размера, операторы перехода и операторы типа кода. И каждый из специальных символов, действующих как разделители, такой как запятая или двоеточие, это отдельный тип сам по себе. Например, два значения, каждое из которых состоит из имени регистра и числового выражения, разделенных запятой, будут распознаны как один тип, независимо от вида регистра и сложности числового выражения; за исключением строк, заключенных в кавычки и значений с плавающей точкой, которые относятся к специальным видом числовых выражений и распознаются как разные типы. Поэтому условие «<code>eax,16 eqtype fs,3+7</code>» является истиной, но «<code>eax,16 eqtype eax,1.6</code>» — ложь.</p>
    </section>
    <section>
     <title>
      <p>2.2.2 Повторение блоков инструкций</p>
     </title>
     <p>«<code>times</code>» повторяет одну инструкцию указанное количество раз. За ней должно следовать числовое выражение, определяющее количество повторений, и инструкция, которую нужно повторять (опционально для того, чтобы отделить число и инструкцию, можно использовать двоеточие). Специальный символ «<code>%</code>», использующийся внутри инструкции, эквивалентен номеру текущего повтора. Например, «<code>times 5 db %</code>» определит пять байтов со значениями 1, 2, 3, 4, 5. Поддерживается также рекурсивное использование директивы «<code>times</code>», например, «<code>times 3 times % db %</code>» определит шесть байтов со значениями 1, 1, 2, 1, 2, 3.</p>
     <p>«<code>repeat</code>» повторяет целый блок инструкций. За ней должно следовать числовое выражение, определяющее количество повторений. Инструкции для повторения предполагаются на следующих строках, а заканчиваться блок должен директивой «<code>end repeat</code>», например:</p>
     <p><code>repeat 8</code></p>
     <p><code> mov byte [bx],%</code></p>
     <p><code> inc bx</code></p>
     <p><code>end repeat</code></p>
     <p>Сгенерированный код сохраняет байты со значениями от одного до восьми в памяти, адресованной регистром BX.</p>
     <p>Количество повторений может быть равным нулю, и в таком случае инструкции не будут ассемболироваться вовсе.</p>
     <p>«<code>break</code>» позволяет остановить повторение раньше и продолжить ассемблирование с первой строки после «<code>end repeat</code>». В сочетании с директивой «<code>if</code>» она позволяет остановить повторение при выполнении некоторого особого условия, например:</p>
     <p><code>s = x/2</code></p>
     <p><code>repeat 100</code></p>
     <p><code> if x/s = s</code></p>
     <p><code>  break</code></p>
     <p><code> end if</code></p>
     <p><code> s = (s+x/s)/2</code></p>
     <p><code>end repeat</code></p>
     <p>«<code>while</code>» повторяет блок инструкций, пока выполняется следующее за ней условие, определенное логическим выражением. Блок инструкций для повторения должен заканчиваться директивой «<code>end while</code>». Перед каждым повторением логическое выражение вычисляется и если его значение ложь, ассемблирование продолжается, начиная с первой строки после «<code>end while</code>». Также в этом случае символ «<code>%</code>» содержит номер текущего повторения. Директива «<code>break</code>» может быть использована для остановки этого типа цикла так же, как с директивой «<code>repeat</code>». Предыдущий пример может быть переписан с использованием «<code>while</code>» вместо «<code>repeat</code>» таким образом:</p>
     <p><code>s = x/2</code></p>
     <p><code>while x/s</code></p>
     <p><code> s</code></p>
     <p><code> s = (s+x/s)/2</code></p>
     <p><code> if % = 100</code></p>
     <p><code>  break</code></p>
     <p><code> end if</code></p>
     <p><code>end while</code></p>
     <p>Блоки, определенные с использованием «<code>if</code>», «<code>repeat</code>» и «<code>while</code>» могут быть вложены в любом порядке, однако и закрыты в обратном. Директива «break» всегда останавливает обработку бока, который был начат последним либо директивой «<code>repeat</code>», либо «<code>while</code>».</p>
    </section>
    <section>
     <title>
      <p>2.2.3 Адресные пространства</p>
     </title>
     <p>«<code>org</code>» устанавливает адрес, по которому следующий за ней код должен появиться в памяти. За ней должно следовать числовое выражение, указывающее адрес. Эта директива начинает новое адресное пространство, следующий код сам по себе никуда не двигается, но все метки, определенные в нем и значение символа «<code>$</code>» изменяются как если бы он был бы помещен по этому адресу. Тем не менее обязанность поместить во время выполнения код по правильному адресу лежит на программисте.</p>
     <p>«<code>load</code>» позволяет определить константу двоичным значением, загруженным из уже сассемблированного кода. За директивой должно следовать имя константы, затем опционально оператор размера, затем оператор «<code>from</code>» и числовое выражение, определяющее валидный адрес в текущем адресном пространстве. Оператор размера здесь имеет необычное значение — он определяет, сколько байтов (до 8) должно быть загружено из двоичного значения константы. Если оператор размера не определен, загружается один байт (таким образом значение оказывается в пределах от 0 до 255). Загруженные данные не могут превосходить текущее смещение.</p>
     <p>«<code>store</code>» может модифицировать уже сгенерированный код заменой некоторых ранее сгенерированных байтов значением, задаваемым следующим за инструкцией числовым выражением. Перед этим выражением может идти оператор размера, определяющий, насколько длинное значение оно задает, то есть сколько будет сохранено байт. Если оператор размера не задан, подразумевается длина в один байт. Далее должен следовать оператор «<code>at</code>» и числовое выражение, указывающее валидный адрес в текущем адресном пространстве кода. По этому адресу будет сохранено задаваемое значение. Это директива для продвинутого применения и её следует использовать осторожно.</p>
     <p>Обе директивы «<code>load</code>» и «<code>store</code>» ограничены оперированием только в пределах текущего адресного пространства. Символ «<code>$$</code>» всегда равен базовому адресу в текущем адресном пространстве, а символ «<code>$</code>» — это адрес текущей позиции в нём, то есть эти два значения определяют границы действия директив «<code>load</code>» и «<code>store</code>».</p>
     <p>Сочетая директивы «<code>load</code>» и «<code>store</code>» можно делать вещи, такие как шифрование некоторого из уже сгенерированного кода. Например, для шифрования всего кода, сгенерированного в текущем адресном пространстве вы можете использовать такой блок директив:</p>
     <p><code>repeat $-$$</code></p>
     <p><code> load a byte from $$+%-1</code></p>
     <p><code> store byte a xor c at $$+%-1</code></p>
     <p><code>end repeat</code></p>
     <p>и каждый байт коза будет проксорен со значением, определенным константой «<code>c</code>».</p>
     <p>«<code>virtual</code>» определяет виртуальные данные по указанному адресу. Эти данные не будут включены в файл вывода, но но метки, определенные здесь, могут использоваться в других частях кода. За этой директивой может следовать оператор «<code>at</code>» и числовое выражение, определяющее адрес виртуальных данных, иначе будет использован текущий адрес, что равносильно директиве «<code>virtual at $</code>». Инструкции определяемых данных должны быть расположены на следующих строках и заканчиваться директивой «<code>end virtual</code>». Блок виртуальных инструкций сам по себе независимое адресное пространство, и после того, как оно заканчивается, восстанавливается контекст предыдущего адресного пространства.</p>
     <p>Директива «<code>virtual</code>» может быть использована для создания объединения нескольких переменных, например:</p>
     <p><code>GDTR dp?</code></p>
     <p><code>virtual at GDTR</code></p>
     <p><code> GDT_limit dw?</code></p>
     <p><code> GDT_address dd?</code></p>
     <p><code>end virtual</code></p>
     <p>Здесь определяются две части 48-битной переменной по адресу «<code>GDTR</code>».</p>
     <p>Директива также может быть использована для определения меток некоторых структур, адресованных регистром, например:</p>
     <p><code>virtual at bx</code></p>
     <p><code> LDT_limit dw?</code></p>
     <p><code> LDT_address dd?</code></p>
     <p><code>end virtual</code></p>
     <p>С таким определением инструкция «<code>mov ax,[LDT_limit]</code>» будет сассемблирована в «<code>mov ax,[bx]</code>».</p>
     <p>Также может быть полезно объявление инструкций и значений данных внутри виртуально блока, так как директиву «<code>load</code>» можно использовать для загрузки в константы значений из виртуально сгенерированного кода. Эта директива должна быть использована после загружаемого кода, но до окончания виртуального блока, так как она может загружать значения только из того же адресного пространства. Например:</p>
     <p><code>virtual at 0</code></p>
     <p><code> xor eax,eax</code></p>
     <p><code> and edx,eax</code></p>
     <p><code> load zeroq dword from 0</code></p>
     <p><code>end virtual</code></p>
     <p>Этот кусок кода определяет константу «<code>zeroq</code>», которая будет содержать четыре байта машинного кода инструкций, указанных внутри виртуального блока. Этот метод также может быть использован для загрузки некоторых бинарных значений из внешнего файла. Например этот код:</p>
     <p><code>virtual at 0</code></p>
     <p><code> file 'a.txt':10h,1</code></p>
     <p><code> load char from 0</code></p>
     <p><code>end virtual</code></p>
     <p>загружает один байт со смещением 10h из файла «<code>a.txt</code>» в константу «<code>char</code>».</p>
     <p>Все директивы «<code>section</code>», описанные в 2.4, также начинают новое адресное пространство.</p>
    </section>
    <section>
     <title>
      <p>2.2.4 Другие директивы</p>
     </title>
     <p>«<code>align</code>» выравнивает код или данные по указанной границе. За ней должно следовать числовое выражение, определяющее количество байтов, на кратность которому должен быть выровнен текущий адрес. Значение границы должно быть степенью двойки.</p>
     <p>Директива «<code>align</code>» заполняет байты, которые должны быть пропущены, чтобы совершить выравнивание, инструкциями «<code>nop</code>», и в это же время маркирует эту область как неинициализированные данные, то есть если её поместить среди других неинициализированных данных, это не займет места в файле вывода, выравнивание байтов происходит таким же образом. Если вам нужно заполнить область выравнивания какими-то другими значениями, вы можете сочетать «<code>align</code>» и «<code>virtual</code>», чтобы получить требуемый размер выравнивания и далее создать выравнивание самостоятельно, например:</p>
     <p><code>virtual</code></p>
     <p><code> align 16</code></p>
     <p><code> a = $ — $$</code></p>
     <p><code>end virtual</code></p>
     <p><code>db a dup 0</code></p>
     <p>Константа «<code>a</code>» определяется как разница между адресом после выравнивания и адресом блока «<code>virtual</code>» (смотрите предыдущий параграф), то есть она равна размеру требуемого пространства выравнивания.</p>
     <p>«<code>display</code>» во время ассемблирования показывает сообщение. За ней должны следовать строка в кавычках или значения байтов, разделенные запятыми. Директива может быть использована для показа значений некоторых констант, например:</p>
     <p><code>bits = 16</code></p>
     <p><code>display 'Current offset is 0x'</code></p>
     <p><code>repeat bits/4</code></p>
     <p><code> d = '0' + $ shr (bits-%*4) and 0Fh</code></p>
     <p><code> if d&gt; '9'</code></p>
     <p><code>  d = d + 'A'-'9'-1</code></p>
     <p><code> end if</code></p>
     <p><code> display d</code></p>
     <p><code>end repeat</code></p>
     <p><code>display 13,10</code></p>
     <p>Этот блок директив рассчитывает четыре цифры 16-битного значения и конвертирует их в знаки для показа. Помните что это не будет работать, если адреса в текущем адресном пространстве перемещаемы (как это может быть с объектным форматом вывода и форматом PE), так как таким образом могут быть использованы только абсолютные значения. Абсолютное значение может быть получено вычислением относительного адреса, например «<code>$-$$</code>» или «<code>rva $</code>» в случае формата PE.</p>
    </section>
    <section>
     <title>
      <p>2.2.5 Множественные проходы</p>
     </title>
     <p>Так как ассемблер позволяет ссылаться на некоторые метки и константы перед тем, как они фактически определены, приходится прогнозировать значения этих меток и если есть даже подозрение, что прогноз окажется неверным хотя бы один раз, делается еще один проход, ассемблирующий весь код, и в это время делается лучший прогноз, базирующееся на значениях меток, полученных в предыдущий проход.</p>
     <p>Изменение значений меток может быть причиной того, что некоторые инструкции перекодируются с другими длинами и это снова повлечет изменение меток. И так как метки и константы ещё могут использоваться внутри выражений, которые влияют на поведение директив управления, весь блок инструкций в новый проход может ассемблироваться абсолютно по-другому. Поэтому ассемблер делает проходы снова и снова, каждый раз пытаясь создать лучшие прогнозы, чтобы приблизиться к финальному решению, когда все значения спрогнозированы правильно. Для прогнозов используются разные методы, которые выбираются с тем, чтобы найти с как можно меньшим количеством проходов решение наименьшей возможной длины для большинства программ.</p>
     <p>О некоторых ошибках, таких как непопадание значений в заданные границе, не сигнализируется во время этих промежуточных проходов, пока может случиться такое, что если какие-то значения будут спрогнозированы лучше, эти ошибки исчезнут сами собой. Однако, если ассемблер встречает какую-то недопустимую синтаксическую конструкцию или неизвестную инструкцию, он всегда останавливается немедленно. Такую же ошибку вызывает определение метки более, чем один раз, так как это делает прогнозы необоснованными.</p>
     <p>Если в коде встречается директива «<code>display</code>», фактически отображаются только сообщения, созданные в последний совершённый проход. В случае, если ассемблер остановился из-за ошибки, эти сообщения могут отражать спрогнозированные значения, которые еще не разрешены правильно.</p>
     <p>Разрешение иногда может не создаться и в таких случаях ассемблер никогда не сумеет создать правильные прогнозы — по этой причине существует предел количества походов, и когда ассемблер исчерпает этот лимит, он остановится отобразит сообщение, что невозможно сгенерировать корректный вывод. Рассмотрим следующий пример:</p>
     <p><code>if ~ defined alpha</code></p>
     <p><code> alpha:</code></p>
     <p><code>end if</code></p>
     <p>Если оператор «<code>defined</code>» выдает значение истина, если выражение, следующее за ним, в этом месте может быть вычислено, что в данном случае означает, что метка «<code>alpha</code>» где-то определена. Но блок выше определяет эту метку только, если значение, данное оператором «<code>defined</code>» ложь, что ведет к противоречию и делает невозможным разрешить такой код. Если, обрабатывая директиву «<code>if</code>» ассемблер должен прогнозировать, будет ли где-нибудь определена метка «<code>alpha</code>» (этого делать не приходится только если метка уже определена раньше), то какой бы ни был прогноз, всегда происходит противоположное. Поэтому ассемблирование остановится, если только метка «<code>alpha</code>» не определена где-то в коде перед вышеуказанным блоком — в этом случае, как уже было отмечено прогнозирование не требуется и блок просто будет пропущен.</p>
     <p>Предыдущий пример может быть создан как попытка определить метку, только если этого все ещё не сделано. Эти строк неправильны, поскольку оператор «<code>defined</code>» проверяет определена ли метка где-либо вообще, и это включает определение внутри этого условного блока. Однако есть способ обойти эту проблему:</p>
     <p><code>if ~ defined alpha | defined @f</code></p>
     <p><code> alpha:</code></p>
     <p><code> @@:</code></p>
     <p><code>end if</code></p>
     <p>«<code>@f</code>» это всегда та же метка, что ближайший следующий за ним символ «<code>@@</code>», поэтому предыдущий пример значит то же, как если бы вместо анонимной метки было определено любое уникальное имя. Если метка «<code>alpha</code>» ещё не определена, ассемблер спрогнозирует значение «<code>defined alpha</code>» как ложь, это будет однако значить, что будут определены обе метки. Но на следующем проходе ассемблер спрогнозирует, что определены обе метки, что заставит определить их вновь — так прогноз будет совпадать с результатом и процесс ассемблиования придет к правильному решению. Анонимная метка выступает здесь как маркер того, что метка «<code>alpha</code>» определена в этом месте.</p>
     <p>Из этого примера вы можете заключить, что прогноз для оператора «<code>defined</code>» очень прямолинейный — метка прогнозируется как определенная только если она была определена в предыдущий проход (а если она была определена в текущий проход, прогноз не требуется). То же самое относится к оператору «<code>used</code>». Однако прогнозы для значений меток не так просты и вам никогда не следует полагать, что ассемблер работает таким способом.</p>
    </section>
   </section>
   <section>
    <title>
     <p>2.3 Директивы препроцессора</p>
    </title>
    <section>
     <p>Все директивы препроцессора выполняются перед основным ассемблированием, и таким образом директивы управления на них никак не влияют. В это время также удаляются все комментарии.</p>
    </section>
    <section>
     <title>
      <p>2.3.1 Включение файлов-исходников</p>
     </title>
     <p>«<code>include</code>» включает указанный файл-исходник туда, где эта директива используется. За ней должно следовать в кавычках имя файла, который должен быть включен, например:</p>
     <p><code>include 'macros.inc'</code></p>
     <p>Весь включенный файл обрабатывается препроцессором перед обработкой строк, следующих за содержащей директиву «<code>include</code>». Нет предела для количества включаемых файлов, пока они умещаются в память.</p>
     <p>Путь, заключенный в скобки, может содержать окружающие переменные, заключенные в знаки «<code>%</code>», они будут заменены на их значения внутри пути. Знаки «<code>\</code>» и «<code>/</code>» трактуются как разделители пути. Если не указан абсолютный путь, сначала файл ищется в директории, содержащей файл, в который он включается, и, далее, если его там нет, в директории, содержащей главный файл-исходник (указанный в командной строке). Эти правила так же относятся к путям, которые указываются в директиве «<code>file</code>».</p>
    </section>
    <section>
     <title>
      <p>2.3.2 Символьные константы</p>
     </title>
     <p>Символьные константы отличаются от числовых констант тем, что перед процессом ассемблирования они заменяются на их значения во всех строках кода, следующих за их определением, и все может стать их значением.</p>
     <p>Определение символьных констант состоит из имени константы, за которой следует директива «<code>equ</code>». Все, что следует за этой директивой, станет значением константы. Если значение символьной константы содержит другие символьные константы, они заменяются на их значения перед присвоением значения новой константе. Например:</p>
     <p><code>d equ dword</code></p>
     <p><code>NULL equ d 0</code></p>
     <p><code>d equ edx</code></p>
     <p>После этих трех определений значение «<code>NULL</code>» будет «<code>dword 0</code>», а значение «<code>d</code>» будет «<code>edx</code>». Так, например, «<code>push NULL</code>» будет сассемблировано как «<code>push dword 0</code>», а «<code>push d</code>» как «<code>push edx</code>». А, например, в такой строке:</p>
     <p><code>d equ d,eax</code></p>
     <p>константе «<code>d</code>» будет присвоено новое значение «<code>edx,eax</code>». Таким образом могут определяться растущие списки символов.</p>
     <p>«<code>restore</code>» позволяет присвоить назад предыдущее значение переопределенной константы. За ней должно следовать одно или больше имен символьных констант, разделенных запятыми. Так, «<code>restore d</code>» после предыдущего переопределения вернет константе значение «<code>edx</code>», следующее применение этой директивы вернет ей значение «<code>dword</code>», а ещё одно применение восстановит первоначальное значение, как будто такая константа не определялась. Если не константа с заданным именем не определена, то «<code>restore</code>» не вызовет ошибку, а будет просто проигнорирована.</p>
     <p>Символьные константы могут использоваться для адаптации синтаксиса ассемблера к персональным предпочтениям. Например, следующие определения создают удобные ярлыки для всех операторов размера:</p>
     <p><code>b equ byte</code></p>
     <p><code>w equ word</code></p>
     <p><code>d equ dword</code></p>
     <p><code>p equ pword</code></p>
     <p><code>f equ fword</code></p>
     <p><code>q equ qword</code></p>
     <p><code>t equ tword</code></p>
     <p><code>x equ dqword</code></p>
     <p>Так как символьная константа может так же иметь пустое значение, она может использоваться для того, чтобы допустить синтаксис со словом «<code>offset</code>» перед каким-нибудь значением адреса:</p>
     <p><code>offset equ</code></p>
     <p>После такого определения «<code>mov ax, offset char</code>» будет правильной конструкцией, которая будет копировать смещение переменной «<code>char</code>» в регистр «<code>ax</code>», так как «<code>offset</code>» заменяется пустым значением, и поэтому игнорируется.</p>
     <p>Символьные константы могут также быть определены директивой «<code>fix</code>», которая имеет такой же синтаксис, как «<code>equ</code>», но определяет константы высшего приоритета — они заменяются их символическим значением даже перед совершением директив препроцессора и макроинструкций. Исключением является сама директива «<code>fix</code>», которая имеет наивысший возможный приоритет, и поэтому допускает переопределение констант, заданных таким путем. Но если такие константы высшего приоритета находятся внутри значения, следующего за директивой «<code>fix</code>», они заменяются их значениями перед присвоением этого значения новой константе.</p>
     <p>Директива «<code>fix</code>» может использоваться для адаптирования директив препроцессора, что нельзя сделать директивой «<code>equ</code>». Например:</p>
     <p><code>incl fix include</code></p>
     <p>определяет короткое имя для директивы «<code>include</code>», тогда как такое же определение директивой «<code>equ</code>» не даст такого результата, так как стандартные символьные константы заменяются на из значения после поиска строк с директивами препроцессора.</p>
    </section>
    <section>
     <title>
      <p>2.3.3 Макроинструкции</p>
     </title>
     <p>«<code>macro</code>» позволяет вам определить собственный комплекс инструкций, называемых макроинструкциями. Их использование может существенно упростить процесс программирования. В своей простейшей форме директива похожа на описание символьной константы. Например, следующая строка определяет ярлык для инструкции «<code>test al,0xFF</code>»:</p>
     <p><code>macro tst {test al,0xFF}</code></p>
     <p>После директивы «<code>macro</code>» должно идти имя макроинструкции и далее её содержание, заключенное между знаками «<code>{</code>» и «<code>}</code>». Вы можете использовать инструкцию «<code>tst</code>» в любом месте после её определения и она будет ассемблирована как «<code>test al,0xFF</code>». Определение символьной константы с таким значением даст похожий результат, различие лишь в том, что имя макроинструкции будет распознаваться только как мнемоник инструкции. Также, макроинструкции заменяются соответствующим кодом даже перед заменой символьных констант на их значения. То есть, если вы вы определите макроинструкцию и символьную константу под одним и тем же именем и используете это имя как мнемоник инструкции, оно будет заменено на содержание макроинструкции, но если вы используете его внутри операндов, имя будет заменено на значение символьной константы.</p>
     <p>Определение макроинструкции может сотоять из нескольких строк, потому что знаки «<code>{</code>» и «<code>}</code>» не обязательно должны находиться на одной строке директивой «<code>macro</code>». Например:</p>
     <p><code>macro stos0</code></p>
     <p><code>{</code></p>
     <p><code> xor al,al</code></p>
     <p><code> stosb</code></p>
     <p><code>}</code></p>
     <p>Макроинструкция «<code>stos0</code>» будет заменена на эти две инструкции ассемблера, где бы он не использовался.</p>
     <p>Как и инструкции, которым требуются несколько операндов, для макроинструкции можно задать требование нескольких аргументов, разделяя их запятыми. Имена этих аргументов должны следовать за именем макроинструкции на строке с директивой «<code>macro</code>». В любом месте в макроинструкции, где эти имена появятся, они будут заменены соостветствующими значениями, указанными там, где макроинструкция используется. Вот пример макроинструкции, которая делает выравнивание данных для двоичного формата вывода:</p>
     <p><code>macro align value { rb (value-1)-($+value-1) mod value }</code></p>
     <p>Когда инструкция «<code>align 4</code>» встречается после этого задания макроинструкции, она заменяется на его содержание, и здесь «<code>value</code>» станет 4, а результат будет «<code>rb (4–1)-($+4–1) mod 4</code>».</p>
     <p>Если в определении макроинструкции встречается её же имя, то используется предыдущее значение этого имени. Таким образом могут быть сделаны полезные переопределения макросинструкций, например:</p>
     <p><code>macro mov op1,op2</code></p>
     <p><code>{</code></p>
     <p><code> if op1 in</code></p>
     <p><code>  &amp; op2 in</code></p>
     <p><code>  push op2</code></p>
     <p><code>  pop op1</code></p>
     <p><code> else</code></p>
     <p><code>  mov op1,op2</code></p>
     <p><code>end if</code></p>
     <p><code>}</code></p>
     <p>Эта макроинструкция расширяет синтаксис инструкции «<code>mov</code>», позволяя обоим операндам быть сегментными регистрами. Например, «<code>mov ds,es</code>» будет ассемблировано как «<code>push es</code>» и «<code>pop ds</code>». Во всех других случаях будет использована стандартная инструкция «<code>mov</code>». Синтаксис этого «<code>mov</code>» может быть расширен далее определением следующей макроинструкции с таким именем, который будет использовать предыдущий:</p>
     <p><code>macro mov op1,op2,op3</code></p>
     <p><code>{</code></p>
     <p><code> if op3 eq</code></p>
     <p><code>  mov op1,op2</code></p>
     <p><code> else</code></p>
     <p><code>  mov op1,op2</code></p>
     <p><code>  mov op2,op3</code></p>
     <p><code>end if</code></p>
     <p><code>}</code></p>
     <p>Это позволяет инструкции «<code>mov</code>» иметь три операнда, но она так же все ещё может иметь два операнда, так как если макроинструкции задается меньше аргументов, чем ему требуется, оставшиеся заполняются пустыми значениями. Если заданы три операнда, то макроинструкция превратится в две ранее определенных, то есть «<code>mov es,ds,dx</code>» будет ассемблировано как «<code>push ds</code>», «<code>pop es</code>» и «<code>mov ds,dx</code>».</p>
     <p>Если требуется создать макроинструкцию с аргументом, который содержит запятые, этот аргумент следует заключить между «<code>&lt;</code>» и «<code>&gt;</code>». Если он содержит больше одного знака «<code>&lt;</code>», то для окончания его описания должно быть использовано такое же количество «<code>&gt;</code>».</p>
     <p>«<code>purge</code>» позволяет отменить последнее определение указанной макроинструкции. За директивой должно следовать одно или больше имен макроинструкций, разделенных запятыми. Если указанная макроинструкция не определена, это не вызовет ошибку. Например, после расширения синтаксиса «<code>mov</code>» вышеуказанными макроинструкциями вы можете отключить синтаксис с тремя операндами, используя директиву «<code>purge mov</code>». Следующее «<code>purge mov</code>» отключит синтаксис для сегментных регистров, а дальнейшее применение этой директивы не возымеет эффекта.</p>
     <p>Если после директивы «<code>macro</code>» вы заключаете некоторую группу аргументов в квадратные скобки, это позволит при использовании макроинструкции задать данной группе аргументов больше значений. Любой следующий аргумент данный после последнего аргумента данной группы начнет новую группу и станет её первым членом. Поэтому после закрытия квадратных скобок не должно быть имен аргументов. Содержание макроинструкции будет обрабатываться для каждой такой группы аргументов отдельно. Простейший пример — это заключение одного имени аргумента в квадратные скобки:</p>
     <p><code>macro stoschar [char]</code></p>
     <p><code>{</code></p>
     <p><code> mov al,char</code></p>
     <p><code> stosb</code></p>
     <p><code>}</code></p>
     <p>Эта макроинструкция допускает неограниченное число аргументов, и каждый будет обработан этими двумя инструкциями отдельно. Например, «<code>stoschar 1,2,3</code>» будет ассемблирован как следующие инструкции:</p>
     <p><code>mov al,1</code></p>
     <p><code>stosb</code></p>
     <p><code>mov al,2</code></p>
     <p><code>stosb</code></p>
     <p><code>mov al,3</code></p>
     <p><code>stosb</code></p>
     <p>Существуют некоторые специальные директивы, возможные только внутри определений макроинструкций. Директива «<code>local</code>» задает локальные имена, которые будут заменены уникальными значениями каждый раз, когда используется макроинструкция. За ней должны следовать имена, разделенные запятыми. Эта директива обычно требуется для внутренних констант или меток макроинструкции. Например:</p>
     <p><code>macro movstr</code></p>
     <p><code>{</code></p>
     <p><code> local move</code></p>
     <p><code> move:</code></p>
     <p><code> lodsb</code></p>
     <p><code> stosb</code></p>
     <p><code> test al,al</code></p>
     <p><code> jnz move</code></p>
     <p><code>}</code></p>
     <p>Каждый раз, когда используется эта макроинструкция, «<code>move</code>» заменяется новым уникальным именем. То есть вы не получите ошибку, это обычный случай, когда метка определяется больше, чем один раз.</p>
     <p>«<code>forward</code>», «<code>reverse</code>» и «<code>common</code>» делят макроинструкцию на блоки, каждый из которых обрабатывается после окончания обработки предыдущего. Они различаются в поведении только если макроинструкция поддерживает много групп аргументов. Блок инструкций, следующий за «<code>forward</code>» будет обрабатываться для каждой группы аргументов от первой до последней, как блок по умолчанию (без этих директив). Блок, идущий за «<code>reverse</code>» будет обрабатываться для каждой группы аргументов в обратном порядке — от последней до первой. Блок за директивой «<code>common</code>» обрабатывается лишь один раз, просто для всех групп аргументов. Локальное имя, определенное в одном блоке, доступно во всех следующих блоках при обработке той же группы аргументов. Если оно было определено в блоке «<code>common</code>», оно доступно во всех следующих блоках, независимо от обрабатываемой группы.</p>
     <p>Вот пример макроинструкции, которая создает таблицу адресов строк и следующих за ними строк.</p>
     <p><code>macro strtbl name,[string]</code></p>
     <p><code>{</code></p>
     <p><code> common</code></p>
     <p><code> label name dword</code></p>
     <p><code> forward</code></p>
     <p><code> local label</code></p>
     <p><code> dd label</code></p>
     <p><code> forward</code></p>
     <p><code> label db string,0</code></p>
     <p><code>}</code></p>
     <p>Первый аргумент, задаваемый этой макроинструкции, станет меткой для таблицы адресов, следующими аргументами должны быть строки. Первый блок обрабатывается однажды и определяет метку, второй блок назначает локальную метку для каждой строки и определяет запись в таблице, содержащий адрес этой строки. Третий блок определяет данные каждой строки с соответствующей меткой.</p>
     <p>Первая инструкция, следующая за директивой, начинающей блок в макроинструкции, может идти с ней на той же строке, как на следующем примере:</p>
     <p><code>macro stdcall proc,[arg]</code></p>
     <p><code>{</code></p>
     <p><code> reverse push arg</code></p>
     <p><code> common call proc</code></p>
     <p><code>}</code></p>
     <p>Это макрос может применяться для вызова процедур, используя соглашение STDCALL, аргументы сохраняются в стеке в обратном порядке. Например, «<code>stdcall foo,1,2,3</code>» будет ассемблировано так:</p>
     <p><code>push 3</code></p>
     <p><code>push 2</code></p>
     <p><code>push 1</code></p>
     <p><code>call foo</code></p>
     <p>Если некоторое имя внутри макроинструкции имеет несколько значений (это либо один из аргументов, заключенных в квадратные скобки, либо локальное имя, определенное в блоке, следующем за директивой «<code>forward</code>» или «<code>reverse</code>») и используется в блоке, следующем за директивой «<code>common</code>», оно будет заменено на все значения, разделенные запятыми. Например, следующий макрос передать все дополнительные аргументы ранее определенной макроинструкции «<code>stdcall</code>»:</p>
     <p><code>macro invoke proc,[arg]</code></p>
     <p><code>{ common stdcall [proc],arg }</code></p>
     <p>Он может применяться для непрямого вызова (через указатель в памяти) процедуры, используя соглашение STDCALL.</p>
     <p>Внутри макроинструкции также может быть использован специальный оператор «<code>#</code>». Этот оператор сцепляет два имени в одно. Это может быть полезно, так как делается после того, как аргументы и локальные имена заменяются на свои значения. Следующая макроинструкция генерирует условный переход в зависимости от аргумента «<code>cond</code>»:</p>
     <p><code>macro jif op1,cond,op2,label</code></p>
     <p><code>{</code></p>
     <p><code> cmp op1,op2</code></p>
     <p><code> j#cond label</code></p>
     <p><code>}</code></p>
     <p>Например, «<code>jif ax,ae,10h,exit</code>» будет ассемблировано как инструкции «<code>cmp ax,10h</code>» и «<code>jae exit</code>».</p>
     <p>Оператор «<code>#</code>» может также использоваться для объединения двух строк, заключенных в кавычки.</p>
     <p>Возможно преобразование имени в строку в кавычках с помощью оператора «<code>`</code>», который также может быть использован внутри макроинструкции. Он конвертирует следующее за ним имя в строку, заключенную в скобки, но имейте в виду, что если за ним следует аргумент, который заменяется на значение, содержащее больше, чем один символ, будет преобразован только первый из них, так как оператор «<code>`</code>» конвертирует только символ, идущий непосредственно за ним. Здесь пример использования этих двух свойств:</p>
     <p><code>macro label name</code></p>
     <p><code>{</code></p>
     <p><code> label name</code></p>
     <p><code> if ~ used name</code></p>
     <p><code>  display `name # "is defined but not used.",13,10</code></p>
     <p><code> end if</code></p>
     <p><code>}</code></p>
     <p>Если метка, определенная таким макросом, не используется в коде, он известит вас об этом сообщением, указывающим, к какой метке это относится.</p>
     <p>Чтобы создать макроинструкцию, ведущую себя по-разному в зависимости от типа аргументов, например если это строки в кавычках, вы можете использовать оператор сравнения «<code>eqtype</code>». Вот пример его использования для отделения строки в кавычках от других типов аргументов:</p>
     <p><code>macro message arg</code></p>
     <p><code>{</code></p>
     <p><code> if arg eqtype ""</code></p>
     <p><code>  local str</code></p>
     <p><code>  jmp @f</code></p>
     <p><code>  str db arg,0Dh,0Ah,24h</code></p>
     <p><code>  @@:</code></p>
     <p><code>  mov dx,str</code></p>
     <p><code> else</code></p>
     <p><code>  mov dx,arg</code></p>
     <p><code> end if</code></p>
     <p><code> mov ah,9</code></p>
     <p><code> int 21h</code></p>
     <p><code>}</code></p>
     <p>Вышеописанный макрос создан для показа сообщений в программах DOS. Если аргумент этого макроса некоторое число, метка или переменная, показывается строка из этого адреса, но если аргумент — это строка в кавычках, то созданный код покажет её после … и … .</p>
     <p>Также возможно объявить макроинструкцию внутри другой макроинструкции, то есть один макрос может определить другой, но с такими определениями есть проблема, вызванная тем, что знак «<code>}</code>» не может появляться внутри макроинструкции, он всегда означает конец его определения. Чтобы обойти эту проблему, можно избавиться от мешающих символов. Это делается путем подстановки одного или больше обратных слэшей перед любыми другими символами (даже специальными знаками). Препроцессор видит эту последовательность как один символ, но каждый раз, когда он видит такой символ во время обработки макроса, он обрезает обратные слэши с его начала. Например, «<code>\{</code>» трактуется как один символ, но во время обработки макроса он станет символом «<code>\{</code>». Это позволит вам определить одну макроинструкцию внутри другой:</p>
     <p><code>macro ext instr</code></p>
     <p><code>{</code></p>
     <p><code> macro instr op1,op2,op3</code></p>
     <p><code> \{</code></p>
     <p><code>  if op3 eq</code></p>
     <p><code>   instr op1,op2</code></p>
     <p><code>  else</code></p>
     <p><code>   instr op1,op2</code></p>
     <p><code>   instr op2,op3</code></p>
     <p><code>  end if</code></p>
     <p><code> \}</code></p>
     <p><code>}</code></p>
     <p><code>ext add</code></p>
     <p><code>ext sub</code></p>
     <p>Макрос «<code>ext</code>» определен корректно, но когда он используется, символы «<code>\{</code>» и «<code>\}</code>» становятся «<code>{</code>» и «<code>}</code>». То есть когда обрабатывается «<code>ext add</code>», содержание макроса становится действительным определением макроинструкции, и таким образом определяется макрос «<code>add</code>». Так же «<code>ext sub</code>» определяет макрос «<code>sub</code>». Использование символа «<code>\{</code>» не было здесь действительно необходимо, но сделано таким образом для того, чтобы определение было более ясным.</p>
     <p>Если некоторые директивы, специфические для макроинструкций, такие как «<code>local</code>» или «<code>common</code>», требуются в некотором макросе, включенном таким образом, то их можно избежать таким же путем. Исключение символа больше чем одним обратным слэшем так же поддерживается, это позволяет допустить множественные уровни вложения определений макросов.</p>
     <p>Другая техника определения макроинструкций внутри других состоит в использовании директивы «<code>fix</code>», которая становится полезной, когда некоторый макрос только начинает определение другого, без его закрытия. Например:</p>
     <p><code>macro tmacro params</code></p>
     <p><code>{</code></p>
     <p><code>macro params {</code></p>
     <p><code>}</code></p>
     <p><code>MACRO fix tmacro</code></p>
     <p><code>ENDM fix }</code></p>
     <p><code>определяет альтернативный синтаксис определения макросов, который выглядит как:</code></p>
     <p><code>MACRO stoschar char</code></p>
     <p><code>mov al,char</code></p>
     <p><code>stosb</code></p>
     <p><code>ENDM</code></p>
     <p>Имейте в виду, что таким образом заданное определение должно быть создано с применением директивы «<code>fix</code>», так как перед тем, как процессор ищет знак «<code>}</code>» во время определения макроса, обрабатываются только символьные константы высшего приоритета! Может возникнуть проблема, если требуется выполнить некоторые дополнительные задания в конце такого определения, но есть еще одно свойство, которое в таких случаях поможет вам. А именно возможно поместить любую директиву, инструкцию или макроинструкцию сразу после символа «<code>}</code>», который заканчивает макроинструкцию и она будет обработана так же, как если бы была на следующей строке.</p>
    </section>
    <section>
     <title>
      <p>2.3.4 Структуры</p>
     </title>
     <p>«<code>struc</code>» — это специальный вариант директивы «<code>macro</code>», который используется для определения структур данных. Макроинструкции, определенные директивой «<code>struc</code>», когда используются, должны предваряться меткой (как директивы определения данных). Эта метка будет также присоединена к началу каждого имени, начинающегося с точки, в содержании макроинструкции. Макроинструкция, определенная с использованием директивы «<code>struc</code>», может иметь такое же имя, как макросы, определенные с использованием директивы «<code>macro</code>». Структурная макроинструкция не будет мешать обычному макросу, выполняющемуся без метки перед ним и наоборот. Все правила и свойства, касающиеся стандартных макросов, применимы к структурным макроинструкциям.</p>
     <p>Вот пример структуры:</p>
     <p><code>struc point x,y</code></p>
     <p><code>{</code></p>
     <p><code> .x dw x</code></p>
     <p><code> .y dw y</code></p>
     <p><code>}</code></p>
     <p>Например «<code>my point 7,11</code>» определит структуру, помеченную «<code>my</code>», содержащую две переменные: «<code>my.x</code>» со значением 7 и «<code>my.y</code>» со значением 11.</p>
     <p>Еслигде-то в определении структуры находится имя, состоящие из одной лишь точки, оно заменяется на имя метки для данного примера структуры и эта метка таким образом не будет определена автоматически, позволяя полностью задать определение. Следующий пример использует это свойство, чтобы расширить определение директивы «<code>db</code>» с возможностью вычисления размера определяемых данных:</p>
     <p><code>struc db [data]</code></p>
     <p><code>{</code></p>
     <p><code> common</code></p>
     <p><code> . db data</code></p>
     <p><code> .size = $ —.</code></p>
     <p><code>}</code></p>
     <p>Таким образом строка «<code>msg db 'Hello!',13,10</code>» определит так же константу «<code>msg.size</code>», равную размеру определяемых данных в байтах.</p>
     <p>Определение структур данных, адресованных регистрами или абсолютными значениями может быть сделано структурными макроинструкциями с использованием директивы «<code>virtual</code>» (смотрите 2.2.3).</p>
     <p>«<code>restruc</code>» удаляет последнее определение структуры, так же как «<code>purge</code>» делает с макросами и «<code>restore</code>» с символьными константами. Директива имеет тот же синтаксис — за ней должно следовать одно или несколько имен структурных макросов, разделенных запятыми.</p>
    </section>
    <section>
     <title>
      <p>2.3.5 Повторение макроинструкций</p>
     </title>
     <p>Директива «<code>rept</code>» — это специальный вид макроинструкций, который делает заданное число дубликатов блока, заключенного в фигурные скобки. Простой синтаксис — число, следующее за «<code>rept</code>» (это не может быть выражение, так как препроцессор не совершает вычисления, если вам нужны повторения, базирующиеся на выражениях, вычисленных ассемблером, используйте одну из директив, обрабатываемых ассемблером, смотрите 2.2.2), и блок кода, заключенный между знаками «<code>{</code>» и «<code>}</code>». Простейший пример:</p>
     <p><code>rept 5 { in al,dx }</code></p>
     <p>создает пять дубликатов строки «<code>in al,dx</code>». Блок инструкций определяется таким же образом, как для стандартных макросов, и допускаются все специальные операторы и директивы, которые могут использоваться только внутри макроинструкций. Если заданное число равно нулю, блок просто пропускается, как если бы вы определили макрос, но не использовали его. За количеством повторений может следовать имя символа-счетчика, который символьно будет заменяться на номер текущего повторения. Таким образом:</p>
     <p><code>rept 3 counter</code></p>
     <p><code>{</code></p>
     <p><code> byte#counter db counter</code></p>
     <p><code>}</code></p>
     <p><code>Сгенерирует строки:</code></p>
     <p><code>byte1 db 1</code></p>
     <p><code>byte2 db 2</code></p>
     <p><code>byte3 db 3</code></p>
     <p>Механизм повторения, применяемый к блокам «<code>rept</code>» такой же, как тот, что используется для обработки множественных групп аргументов макросов, то есть директивы, такие как «<code>forward</code>», «<code>common</code>» и «<code>reverse</code>» могут использоваться их обычном значении.</p>
     <p>Итак, такой макрос:</p>
     <p><code>rept 7 num { reverse display `num }</code></p>
     <p>покажет символы от 7 до 1 как текст. Директива «<code>local</code>» работает так же, как внутри макросов с несколькими группами аргументов, то есть:</p>
     <p><code>rept 21</code></p>
     <p><code>{</code></p>
     <p><code> local label</code></p>
     <p><code> label: loop label</code></p>
     <p><code>}</code></p>
     <p>сгенерирует уникальную метку для каждого дубликата. Символ-счетчик обычно начинает с 1, но вы можете объявить другое базовое значение, предваренное запятой, сразу же после имени счетчика. Например:</p>
     <p><code>rept 8 n:0 { pxor xmm#n,xmm#n }</code></p>
     <p>Сгенерирует код, очищающий содержимое регистров SSE. Вы можете определить несколько счетчиков, разделенных запятыми, и каждый может иметь свою базу.</p>
     <p>«<code>irp</code>» итерирует один аргумент через данный список параметров. Синтаксис такой: за «<code>irp</code>» следует имя аргумента, далее запятая и далее список параметров. Параметры определяются таким же образом, как в вызове стандартного макроса, то есть они должны разделяться запятыми и каждый может быть заключен между знаками «&lt;» и «&gt;». Так же за именем аргумента может следовать «<code>*</code>» для обозначения того, что он не может иметь пустое значение. Такой блок:</p>
     <p><code>irp value, 2,3,5</code></p>
     <p><code>{ db value }</code></p>
     <p>сгенерирует строки:</p>
     <p><code>db 2</code></p>
     <p><code>db 3</code></p>
     <p><code>db 5</code></p>
     <p>«<code>irps</code>» итерирует через данный список символов, за директивой должно следовать имя аргумента, далее запятая и далее последовательность любых символов. Каждый символ в последовательности, независимо от того, символы ли это имен, знаки символов или строки в кавычках, становится значением аргумента на одну итерацию. Если за запятой никаких символов не следует, то итераций не производится вообще. Этот пример:</p>
     <p><code>irps reg, al bx ecx</code></p>
     <p><code>{ xor reg,reg }</code></p>
     <p>сгенерирует строки:</p>
     <p><code>xor al,al</code></p>
     <p><code>xor bx,bx</code></p>
     <p><code>xor ecx,ecx</code></p>
     <p>Блоки, определенные директивами «<code>irp</code>» и «<code>irps</code>», обрабатываются так же, как макросы, то есть операнды и директивы, специфичные для макросов могут в них свободно использоваться.</p>
    </section>
    <section>
     <title>
      <p>2.3.6 Условный препроцессинг</p>
     </title>
     <p>При применении директивы «<code>match</code>» некоторый блок кода обрабатывается препроцессором и передаётся ассемблеру, только если заданная последовательность символов совпадает с образцом. Образец идет первым, заканчивается запятой, далее идут символы, которые должны подходить под образец, и далее блок кода, заключенный в фигурные скобки, как макроинструкция.</p>
     <p>Есть несколько правил для построения выражения для сравнения, первое — это любые символьные знаки и строки в кавычках должны соответствовать абсолютно точно. В этом примере:</p>
     <p><code>match +,+ { include 'first.inc' }</code></p>
     <p><code>match +,- { include 'second.inc' }</code></p>
     <p>Первый файл будет включен, так как «<code>+</code>» после запятой соответствует «<code>+</code>» в образце, а второй файл не будет включен, так как совпадения нет.</p>
     <p>Чтобы соответствовать любому другому символу буквально, он должен предварятья знаком «<code>=</code>» в образце. Также чтобы привести в соответствие сам знак «<code>=</code>», или запятую должны использоваться конструкции «<code>==</code>» и «<code>=,</code>». Например, образец «<code>=a==</code>» будет соответствовать последовательности «<code>a=</code>».</p>
     <p>Если в образце стоит некоторый символ имени, он соответствует любой последовательности, содержащей по крайней мере один символ и его имя заменяется на поставленную в соответствие последовательность везде в следующем блоке, аналогично параметрам в макроинструкции. Например:</p>
     <p><code>match a-b, 0–7</code></p>
     <p><code>{ dw a,b-a }</code></p>
     <p>сгенерирует инструкцию «<code>dw 0, 7–0</code>». Каждое имя всегда ставится в соответствие как можно меньшему количеству символов, оставляя оставшиеся, то есть:</p>
     <p><code>match a b, 1+2+3 { db a }</code></p>
     <p>имя «<code>a</code>» будет соответствовать символу «<code>1</code>», оставляя последовательность «<code>+2+3</code>» в соответствие с «<code>b</code>». Но, таким образом:</p>
     <p><code>match a b, 1 { db a }</code></p>
     <p>для «<code>b</code>» ничего не остается, и блок вообще не будет обработан.</p>
     <p>Блок кода, определенный директивой «<code>match</code>» обрабатывается так же, как любая макроинструкция, поэтому здесь могут использоваться любые операторы, специфичные для макроинструкций.</p>
     <p>Что делает директиву «<code>match</code>» очень полезной, так это тот факт, что она заменяет символьные константы на их значения в поставленной в соответствие последовательности символов (то есть везде после запятой до начала блока кода) перед началом сопоставления. Благодаря этому директива может использоваться, например, для обработки некоторого блока кода в зависимости от выполнения условия, что данная символьная константа имеет нужное значение, например:</p>
     <p><code>match =TRUE, DEBUG { include 'debug.inc' }</code></p>
     <p>здесь файл будет включен, только если символьная константа «<code>DEBUG</code>» определена со значением «<code>TRUE</code>».</p>
    </section>
    <section>
     <title>
      <p>2.3.7 Порядок обработки</p>
     </title>
     <p>При сочетании разных свойств препроцессора важно знать порядок, в котором они обрабатываются. Кат уже было отмечено, высший приоритет имеет директива «<code>fix</code>» и замены, ею определенные. Это полностью делается перед совершением любого другого препроцессинга, поэтому такой кусок кода:</p>
     <p><code>V fix {</code></p>
     <p><code>  macro empty</code></p>
     <p><code>   V</code></p>
     <p><code>V fix }</code></p>
     <p><code>   V</code></p>
     <p>делает допустимое определение пустого макроса. Можно сказать, что директива «<code>fix</code>» и приоритетные константы обрабатываются на отдельной стадии, и весь остальной препроцессинг делается на результирующем коде.</p>
     <p>Стандартный препроцессинг, который начинается после, на каждой строке начинается с распознавания первого символа. Сначала идет проверка на директивы препроцессора, и если ни одна из них не опознана, препроцессор проверяет, является ли первый символ макроинструкцией. Если макроинструкция не найдена, препроцессор переходит ко второму символу на строке, и снова начинает с проверки на директивы, список которых в этом случае ограничивается лишь «<code>equ</code>», так как только она может оказать вторым символом на строке. Если нет директивы, второй символ проверяется на структурную макроинструкцию, и если ни одна из этих проверок не дала положительного результата, символьные константы заменяются на их значения, и строка передается ассемблеру.</p>
     <p>Продемонстрируем это на примере. Пусть «<code>foo</code>» — это макрос, а «<code>bar</code>» — это структура. Эти строки:</p>
     <p><code>foo equ</code></p>
     <p><code>foo bar</code></p>
     <p>обе будут интерпретированы как вызовы макроса «<code>foo</code>», так как значение первого символа берет верх над значением второго.</p>
     <p>Макроинструкции генерируют новые строки от их блоков определения, заменяя параметры на их значения и далее обрабатывая операторы «<code>#</code>» и «<code>`</code>». Оператор конверсии имеет высший приоритет, чем оператор сцепления.</p>
     <p>После завершения этого, заново сгенерированная строка проходит через стандартный препроцессинг, как описано выше.</p>
     <p>Хотя обычно символьные константы заменяются исключительно в строках, нет ни директив препроцессора, ни макроинструкций, встречается несколько особых ситуаций, где замены проводятся в частях строк, содержащих директивы. Первая — это определение символьной константы, где замены производятся везде после слова «<code>equ</code>» и результирующее значение присваивается новой константе (смотрите 2.3.2). Вторая такая ситуация — это директива «<code>match</code>», где замены производятся в символах, следующих за запятой перед сопоставлением их с образцом. Эти свойства могут использоваться, например, для сохранения списков, как, например, эта совокупность определений:</p>
     <p><code>list equ</code></p>
     <p><code>macro append item</code></p>
     <p><code>{</code></p>
     <p><code> match any, list \{ list equ list,item \}</code></p>
     <p><code> match, list \{ list equ item \}</code></p>
     <p><code>}</code></p>
     <p>Здесь константа «<code>list</code>» инициализируется с пустым значением, и макрос «<code>append</code>» может использоваться для добавления новых пунктов к списку, разделяя их запятыми. Первое сопоставление в этом макросе происходит, только если значение списка непусто (смотрите 2.3.6), таким образом новое его значение — это предыдущее с запятой и новым пунктом, добавленным в конец. Второе сопоставление происходит, только если список все еще пуст, и таким образом список определяется как содержащий только лишь новый пункт. Так, начиная с пустого списка, «<code>append 1</code>» определит «<code>list equ 1</code>», а «<code>append 2</code>», следующий за ним, определит «<code>list equ 1,2</code>». Может потребоваться использовать этот список как параметры к некоторому макросу. Но это нельзя сделать прямо — если «<code>foo</code>» это макрос, то в строке «<code>foo list</code>» символ «<code>list</code>» просто прошел бы как параметр к макросу, поскольку символьные константы на этой стадии ещё не развернуты. Для этой цели снова оказывается удобна директива «<code>match</code>»:</p>
     <p><code>match params, list { foo params }</code></p>
     <p>Значение «<code>list</code>», если оно не пустое, соответствует ключевому слову «<code>params</code>», которое далее во время генерации строк, заключенных в фигурные скобки, заменяется на соответственное значение. Так, если «<code>list</code>» имеет значение «<code>1,2</code>», строка, указанная выше, сгенерирует строку, содержащую «<code>foo 1,2</code>», которая далее пройдет стандартный препроцессинг.</p>
     <p>Есть ещё один особый случай — когда препроцессор собирается проверить второй символ и натыкается на двоеточие (что далее интерпретируется ассемблером как определение метки), он останавливается в этом месте и заканчивает препроцессинг первого символа (то есть если это символьная константа, она развертывается) и если это все еще выглядит меткой, совершается стандартный препроцессинг, начиная с места после метки. Это позволяет поместить директивы препроцессора и макроинструкции после меток, аналогично инструкциям и директивам, обрабатываемым ассемблером, например:</p>
     <p><code>start: include 'start.inc'</code></p>
     <p>Однако если метка во время препроцессинга разрушается (например, если у символьной константы пустое значение), происходит только замена символьных констант до конца строки.</p>
    </section>
   </section>
   <section>
    <title>
     <p>2.4 Директивы форматирования</p>
    </title>
    <section>
     <p>«<code>format</code>» со следующим за ним идентификатором формата позволяет выбрать формат вывода. Эта директива должна стоять в начале кода. Формат вывода по умолчанию — это простой двоичный файл, он может быть также выбран директивой «<code>format binary</code>».</p>
     <p>«<code>use16</code>» и «<code>use32</code>» указывают ассемблеру генерировать 16-битный или 32-битный код, пренебрегая настройкой по умолчанию для выбранного формата вывода. «<code>use64</code>» включает генерирование кода для длинного режима процессоров x86.</p>
     <p>Ниже описаны разные форматы вывода со специфичными для них директивами.</p>
    </section>
    <section>
     <title>
      <p>2.4.1 MZ</p>
     </title>
     <p>Чтобы выбрать формат вывода MZ, используйте директиву «<code>format MZ</code>». По умолчанию код для этого формата 16-битный.</p>
     <p>«<code>segment</code>» определяет новый сегмент, за ним должна следовать метка, чьим значением будет номер определяемого сегмента. Опционально за этой директивой может следовать «<code>use16</code>» или «<code>use32</code>», чтобы указать битность кода в сегменте. Начало сегмента выровнено по параграфу (16 байт). Все метки, определенные далее, будут иметь значения относительно начала этого сегмента.</p>
     <p>«<code>entry</code>» устанавливает точку входа для формата MZ, за ней должен следовать дальний адрес (имя сегмента, двоеточие и смещение в сегменте) желаемой точки входа.</p>
     <p>«<code>stack</code>» устанавливает стек для MZ. За директивой может следовать числовое выражение, указывающее размер стека для автоматического создания, либо дальний адрес начального стекового фрейма, если вы хотите установить стек вручную. Если стек не определен, он будет создан с размером по умолчанию в 4096 байт.</p>
     <p>«<code>heap</code>» со следующим за ней значением определяет максимальный размер дополнительного места в параграфах (это место в добавление к стеку и для неопределенных данных). Используйте «<code>heap 0</code>», Чтобы всегда отводить только память, которая программе действительно нужна.</p>
    </section>
    <section>
     <title>
      <p>2.4.2 PE</p>
     </title>
     <p>Чтобы выбрать формат вывода PE, используйте директиву «<code>format PE</code>», за ней могут следовать дополнительные настройки формата: используйте «<code>console</code>», «<code>GUI</code>» или оператор «<code>native</code>», чтобы выбрать целевую субсистему (далее может следовать значение с плавающей точкой, указывающее версию субсистемы), «<code>DLL</code>» помечает файл вывода как динамическую связывающую библиотеку. Далее может следовать оператор «<code>at</code>» и числовое выражение, указывающее базу образа PE и далее опционально оператор «<code>on</code>» со следующей за ним строкой в кавычках, содержащей имя файла, выбирающей заглушку MZ для PE программы (если указанный файл не в формате MZ, то он трактуется как простой двоичный исполняемый файл и конвертируется в формат MZ). По умолчанию код для этого формата 32-битный. Пример объявления формата PE со всеми свойствами:</p>
     <p><code>format PE GUI 4.0 DLL at 7000000h on 'stub.exe'</code></p>
     <p>«<code>section</code>» определяет новую секцию, за ней должна следовать строка в кавычках, определяющая имя секции, и далее могут следовать один или больше флагов секций. Возможные флаги такие: «<code>code</code>», «<code>data</code>», «<code>readable</code>», «<code>writeable</code>», «<code>executable</code>», «<code>shareable</code>», «<code>discardable</code>», «<code>notpageable</code>». Начало секции выравнивается по странице (4096 байт). Пример объявления секции PE:</p>
     <p><code>section '.text' code readable executable</code></p>
     <p>Вместе с флагами также может быть определен один из специальных идентификаторов данных PE, отмечающий всю секцию как специальные данные, возможные идентификаторы: «<code>export</code>», «<code>import</code>», «<code>resource</code>» и «<code>fixups</code>». Если секция помечена для содержания настроек адресов, они генерируются автоматически, и никаких данных определять больше не требуется. Также данные ресурсов могут быть сгенерированы автоматически из файлов ресурсов, этого можно добиться, написав после идентификатора «<code>resourse</code>» оператор «<code>from</code>» и имя файла в кавычках. Ниже вы можете увидеть примеры секций, содержащих некоторые специальные данные:</p>
     <p><code>section '.reloc' data discardable fixups</code></p>
     <p><code>section '.rsrc' data readable resource from 'my.res'</code></p>
     <p>«<code>entry</code>» создает точку входа для PE, далее должно следовать значение точки входа.</p>
     <p>«<code>stack</code>» устанавливает размер стека для PE, далее должно следовать значение зарезервированного размера стека, опционально может следовать отделенное запятой значение начала стека. Если стек не определен, ему присваивается размер по умолчанию, равный 4096 байт.</p>
     <p>«<code>heap</code>» выбирает размер дополнительного места для PE, далее должно следовать значение для зарезервированного для него места, опционально ещё может быть значение его начала, отделенное запятой. Если дополнительное место не определено, оно ставится по умолчанию равным 65536 байт, если не указано его начало, то оно устанавливается равным 0.</p>
     <p>«<code>data</code>» начинает определение специальных данных PE, за директивой должен следовать один из идентификаторов данных («<code>export</code>», «<code>import</code>», «<code>resource</code>» или «<code>fixups</code>») или номер записи данных в заголовке PE. Данные должны быть определены на следующих строках и заканчиваться директивой «<code>end data</code>». Если выбрано определение настроек адресов, они генерируются автоматически, и никаких данных определять больше не требуется. То же самое относится к ресурсам, если за идентификатором «<code>resourse</code>» следует оператор «<code>from</code>» и имя файла в кавычках — в этом случае данные берутся из этого файла ресурсов.</p>
    </section>
    <section>
     <title>
      <p>2.4.3 COFF</p>
     </title>
     <p>Чтобы выбрать COFF (Common Object File Format), используйте директиву «<code>format COFF</code>» или «<code>format MS COFF</code>», если вы хотите создать классический мелкософтофский файл COFF. По умолчанию код для этого формата 32-битный. Чтобы создать микросфтовский формат COFF для архитектуры x86-64, используйте установку «<code>format MS64 COFF</code>», в этом случае автоматически будет генерироваться код длинного режима.</p>
     <p>«<code>section</code>» определяет новую секцию, за директивой должна следовать строка в кавычках, определяющая имя новой секции, и ещё может следовать один или более флагов секций. Возможные флаги такие: «<code>code</code>» и «<code>data</code>» для обоих вариантов COFF, «<code>readable</code>», «<code>writeable</code>», «<code>executable</code>», «<code>shareable</code>», «<code>discardable</code>» и «<code>notpageable</code>» только для микросовтофского варианта COFF. По умолчанию секция выровнена по двойному слову (четыре байта), но микросовтовский вариант COFF можно выровнять еще как-нибудь по-другому с помощью оператора «<code>align</code>» и следующим за ним значением выравнивания (любая степень двойки от двух до 8192) среди фагов секций.</p>
     <p>«<code>extrn</code>» определяет внешний символ, за ним должно следовать имя символа и опционально оператор размера, указывающий размер данных, помеченных этим символом. Имя символа также может предваряться строкой в кавычках, содержащей имя внешнего символа и оператор «<code>as</code>». Пара примеров объявления внешних символов:</p>
     <p><code>extrn exit</code></p>
     <p><code>extrn <emphasis>'</emphasis>im<emphasis>p</emphasis>MessageBoxA@16' as MessageBox: dword</code></p>
     <p>«<code>public</code>» объявляет существующий символ как общедоступный, за ним должно следовать имя символа, и далее опционально оператор «<code>as</code>» и строка в кавычках, содержащая имя, под которым символ будет действителен как общедоступный. Пара примеров объявления общедоступных символов:</p>
     <p><code>public main</code></p>
     <p><code>public start as '_start'</code></p>
    </section>
    <section>
     <title>
      <p>2.4.4 ELF</p>
     </title>
     <p>Чтобы выбрать формат вывода ELF, используйте директиву «<code>format ELF</code>». По умолчанию код для этого формата 32-битный. Чтобы создать формат ELF для архитектуры x86-64, используйте установку «<code>format ELF</code>», в этом случае автоматически будет генерироваться код длинного режима.</p>
     <p>«<code>section</code>» определяет новую секцию, за директивой должна следовать строка в кавычках, определяющая имя новой секции, и ещё может следовать один или оба флага «<code>executable</code>» и «<code>writeable</code>», опционально также может идти оператор «<code>align</code>» со следующим за ним числом, определяющим выравнивание секции (это должна быть степень двойки), если выравнивание не указано, используется значение по умолчанию, которое равно 4 или 8, в зависимости от варианта выбранного формата.</p>
     <p>«<code>extrn</code>» и «<code>public</code>» имеют те же значения и синтаксис у них, как в случае формата COFF (описанного в предыдущем параграфе).</p>
     <p>Чтобы создать исполняемый файл, придерживайтесь директивы выбора формата со словом «<code>executable</code>». Это позволяет использовать директиву «<code>entry</code>» со следующим за ним значением, чтобы создать точку входа в программу. С другой стороны это делает недоступными директивы «<code>extrn</code>» и «<code>public</code>». За директивой «<code>section</code>» в этом случае может следовать только один или более флагов секций и начало секции будет выровнено по странице (4096 байт). Доступные флаги секций такие: «<code>readable</code>», «<code>writable</code>» и «<code>executable</code>».</p>
    </section>
   </section>
  </section>
 </body>
 <binary id="cover.png" content-type="image/png">iVBORw0KGgoAAAANSUhEUgAAAUAAAAHgBAMAAAAmoql3AAAAMFBMVEX////s7ewEAgQkJiQc
HhxkZmS8urxMTkzU0tSUlpQ8Pjx8fnyMhozc2tykpqS0srQZDWJvAAAEmklEQVR4Ae3X0Yvj
VBTH8VMgSfOWIf/B6bbDPGaWHRX0ZRi0vsVCEd+6s8MM+FRWxrWgWKHKEF9CBxkU8M21iMoK
KD4L/gUCgq/7j5h7CKVhpC47yU5gvwcIze0v9356W+g9stPyehmAAKW91QEIECBAgAABAgQI
ECBAgAAB3moBBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAEC
BAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBBir6p1DVT1S
1V4EECBAgC0CAuzsq2ryYkkAAQIECBAgQIAAmy6AAM11tNmK2IvkP9/qRc/9eGWkFwEECBAg
wEb+SaqZ2JZ6jnD51u0BAQIECBAgQIAAAQIEuL3f2JIxBUCAAAECbMM/yfZqFljOd4MP0WYg
QIAAAQIECBAgQIAc+bc0TevOKLaR+psmgAABAgTY0gIIECBAgAABAgQIECBAgACfuQB6uufr
4NmyYxGx8IsEXkYinYPy5kH0v0ALVyvsi5Xh7a5O4FhuCuy8fq989YF7PPuuXuD5jYHe/RLo
T911Nq4T6KtqYmv6uitL1T2xOtaphNqLiqFEfO1L9senvWi87EVluC/+J/uDcsUS6OUiEibj
ZnbwS4nT9Q52n3Tu2Y2f2M80SBcfvfXXZJQGqQvbiH9nfhlVgMFTTSSeNAQU8Rxw4+s8nhRA
t0mzwpldvOmW9m27bcQfSjavAONE3pWxNAQMVDeAD7Uv3cM9kYXmnX3VNXDowjZim1sFTiT7
ImkK+GhzB4OpLbPIRbpv2/5WdtBGrgODXE4+V9W9RoDncpzKYlIulfp9W9G+4MtoDYzz8jd4
DTjKxR/abPXvoKfal4V+nEpYfvru4e6fsixuQtXcXVIDLnVgYRtZA4ub3QKYiiw1NyCHBYAA
AQIE2Bpg5xUJkjYDu0fzxbDVwB/zb1etBj5+8vvKOpCxeOliIidz15wUI30RKQ86742sOZnK
QjX1vtJEXCZOOnd37kZxUoRTy9g8dQN/+u2XlXUgDug5pzUnVzIWA6YyFteKeIk8suOi15dz
y2Sz8IeL7/NvVmEi55axeWoG+tOr+wciMjagP+yuTFUFuoN0YcvmDlieu700e5q9f/Hzq49X
QV6MuIzNUzsw2zmwDmSkmsosTCVQNVUFOMzmEk9K4MncZR783Y9P33j4zkGs2nPAoc1TO1Dk
w2Ba7qCc/TO35qTz2vYddJkzfxifTk8+O4gnIpaxeWoGhgVwZh2IAYNfxZoTf1gFxrnnfmgF
0PSWORMJTt3nCxMRy9g8TQCtAzFgOBBrTkb5JnCkAykuqRhQdWKZqwL4tXtcltq3jM1TA3C7
93qVVisjb8s0DFxM2g1cDuS2gRy3AAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAg
QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAg
QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECLDVBfAlAP4Ld068BYGoswYAAAAASUVORK5C
YII=</binary>
 <binary id="i_001.png" content-type="image/png">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
SUVORK5CYII=</binary>
 <binary id="i_002.png" content-type="image/png">iVBORw0KGgoAAAANSUhEUgAAAlUAAAFXBAMAAAB5CKYXAAAAMFBMVEUAAAACAAILAAsYABgA
AQAAAwAAAwAHAAcAAQAABQAAAwAEAAQADgAABgAHAAcABADb0G/CAAAAEHRSTlMA/S0V48Ob
Rdhrs3wkW02IxnwOdAAAEQhJREFUeAHtncGL5Nh9x39UGQnpEh4M1V19KpZq8C3FmiS6jlg8
zIIJtNkEcAJqMGXvnqSdJjvMxTSC7YxzUeFh6AwENBvonZ4kBl+C/R/sLZcN5Jr/wMSGXJP3
pfcZkL4tTVEu7O7vg/EW/dFPevWZJ7nr9Xd+bUv34KFz7gPn9OLWF4crO17Z6DF08OT7dnfH
sVzJlVyNHHIlV3IlV3IlV3IlV3IlV3IlV5OHzuWjXZ0619zndXW8GL+u1uPXlVzJVdJOP/f3
VzHCFQ7Gnft0ZVl5D11FM1tbVAw/r45wMKruq6vLq1Gu1pa2OPgeu/ri0Xqkq8kJDvZVlTu4
j64+asa6inMcbFhXT799D10d2Xr8PXhk99pVPdLVqZvhYFRVLr/D96A+48iVXMmVXMmVXMmV
XMmVXMmVXMnVt8flS/XiwWq8Vw2tq/HrSs+r8e/9WzZ2aGhd6XuG++xKruRKruRKruRKruRK
ripXGhkUrQmKClIV6owiCgiKCsCduYrc0fC6ythb42hNUFSg6o/S1SeWFnI1ztWVJa1cjXNV
FVXJXIG7lr211M0ZqtyMufrY1byqtfXmiFyLIFzLI3ItoN24mp7Xxl3Z5NfTz8lb84CgpObr
amZXBOFap0XWkGt5RK7lEbkW0G5cLZtTtq4G7qakpa6ykrsqQtq5O1gWEdciKCtpFa4FtKvn
VVTf5uo1v5sK6mp5q6uzRS/Ctfi7Zq6W3BWutTtX0+cW3+Yqbfm73vW6Slv+rv8g1tWbVdre
5qqI2bqaPDajGlO+GqfPCcK1/Fsj12IaU1aFa+3QVepmtz7bHx79O/t3PUs3J2h6Pn9JUOJc
SRCutbaIXMsjci0gcq3tXenzoFzJlVzJlVztdMiVXMlV5co9uVqb8T0lPratqho6DSDmanrO
t7OzjqtNYRa7g3vpCvA3o11lvyz8h8I/9nU1OA3i6qpLuasfZYXFrd1TV3GOxeUK+/j0cIUX
z75yJXZou64sKyxqqCtfNfnQ0rp/X5ehys0I8vu6rGrjasy5vwqIVFWObmUDMVdJjf+52T7F
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
If8fAzluh/s5W5wAAAAASUVORK5CYII=</binary>
 <binary id="i_003.png" content-type="image/png">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</binary>
 <binary id="i_004.png" content-type="image/png">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</binary>
</FictionBook>
