ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



Часть2. Введение в язык ассемблера
                   
                         ПРИДНЕПРОВСКИЙ ФИЛИАЛ
                  СОВЕТСКО-БОЛГАРО-ФИНСКОГО ПРЕДПРИЯТИЯ
                    "Новые информационные технологии"


                         СИСТЕМА  ПРОГРАММИРОВАНИЯ 
                         НА МАКРОАССЕМБЛЕРЕ MS-DOS

                           Справочное руководство

                     Часть 2. Введение в язык ассемблера   
                     

                         (редакция 1, январь 1989)

                   
                   
                        Днепропетровск 1989г.
                                       
                                         

                                   Содержание


         1. Общие сведения о языке................................. 4
         2. Первичные элементы языка ассемблера.................... 6
         2.1. Алфавит.............................................. 6
         2.2. Идентификаторы, переменные, метки, имена,
              ключевые слова....................................... 6
         2.3. Типы данных.......................................... 8
         2.3.1. Целые числа........................................ 8
         2.3.2. Действительные числа............................... 8
         2.3.3. Десятичные числа................................... 9
         2.3.4. Знаковые и строковые константы..................... 9
         2.4. Предложения..........................................10
         2.5. Комментарии..........................................10
         3. Регистры процессора и способы адресации................12
         4. Выражения..............................................14
         4.1 Операнды выражений....................................14
         4.2. Операторы............................................17
         4.3. Особенности вычисления выражений.....................24
         4.3.1. Приоритеты операций................................24
         4.3.2. Ссылки вперед......................................24
         4.3.3. Контроль типов.....................................25
            
         Приложение 1. Ключевые слова языка ассемблера.............26
         Приложение 2. Регистры и адресация процессора 8088........27

               
               
                        1. Общие сведения о языке.
               
               
               
               Настоящее  руководство  содержит  сведения о первичных
         элементах  языка   ассемблера   системы   MS-DOS   и   может
         представлять интерес для пользователей, впервые приступающих
         к изучению языка ассемблера.
               Язык ассемблера системы MS-DOS реализован  при  помощи
         макроассемблера   MASM  (см.  "Система  программирования  на
         макроассемблере  MS-DOS.  Часть  1.  Пакет   макроассемблера
         MS-DOS",  п.2)  и  представляет собой базовый язык семейства
         микропроцессоров INTEL 8086/80186/80286. Он включает в  себя
         инструкции  процессоров  8086,  8088,  80186  и  80286 и как
         дополнительные  возможности  -   инструкции   арифметики   с
         плавающей  точкой  процессоров  8087  и  80287, работающих в
         режиме сопроцессора.
               Синтаксис    инструкций    процессора    предоставляет
         программисту широкий выбор типов данных: целые числа, строки
         знаков, упакованные  десятичные  числа,  числа  с  плавающей
         точкой, структуры и записи. 
               Язык  ассемблера  имеет мощный набор директив, который
         позволяет    полностью     использовать     сегментированную
         архитектуру процессоров 8086, 80186 и 80286.
               В  языке  имеются директивы условного ассемблирования,
         обеспечивающие выборочное исключение частей исходного текста
         из процесса ассемблирования и, с другой стороны, возможность
         подключения фрагментов исходного текста из других файлов.
               Ассемблер  имеет  набор  макродиректив,  использование
         которых  позволяет относительно просто повторять общие блоки
         предложений несколько раз или заменять макроимена в исходном
         тексте целыми последовательностями предложений.
               Макроассемблер  MASM генерирует переместимый объектный
         код для процессоров 8086, 8088, 80186 и  80286.  Формируемые
         объектные  модули  в целом совместимы с объектными модулями,
         созданными компиляторами языков высокого уровня.
               В  настоящем  руководстве  приняты  следующие условные
         обозначения.
               Конструкция, заключенная в двойные  квадратные  скобки
         [[ ]], может отсутствовать.
               Из нескольких  конструкций,  разделенных символом  | ,
         может быть выбрана только одна.
               Текст,   состоящий   из   букв  русского  алфавита  на
         регистре  строчных  букв  и  других  символов,   разделенных
         символом  -  ,  обозначает  нетерминальные  элементы  и  при
         кодировании   должен   замещаться   требуемыми   по   смыслу
         конструкциями.  

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

                                     -  6 -
               

               
               
               
                    2. Первичные элементы языка ассемблера.

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

               
               Макроассемблер распознает следующий набор знаков:
               
               A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
               a b c d e f g h i j k l m n o p q r s t u v w x y z
               0 1 2 3 4 5 6 7 8 9 
               ? @ _ $ : . [ ] ( ) < > { } 
               + / * & % ! ' ~ | \ = # ^ ; , ` "
               
               
               
               
               
                     2.2. Идентификаторы, переменные,
                       метки, имена, ключевые слова.
               
               
               
               Конструкции   языка    ассемблера    формируются    из
         идентификаторов и ограничителей.
               Идентификатор  представляет  собой  набор букв, цифр и
         символов   _  ,  ?,  $  или  @,  не  начинающийся  с  цифры.
         Идентификатор должен полностью размещаться на одной строке и
         может содержать от 1 до  31  символа  (точнее,  используются
         только    первые   31   символ   идентификатора,   остальные
         игнорируются) . Следует заметить, что  символ  _  ,  хотя  и
         допускается    в    качестве    компоненты   идентификатора,
         ассемблером игнорируется. Поэтому, например,  идентификаторы
         A_B и AB совпадают. 
               Друг от друга идентификаторы  отделяются  пробелом или
         ограничителем,  которым  считается  любой   недопустимый   в
         идентификаторе символ.

                                     -  7 -
         
         
               Посредством  идентификаторов  представляются следующие
         объекты программы:
               1. Переменные.
               2. Метки.
               3. Имена.
               
               Переменные    идентифицируют   хранящиеся   в   памяти
         данные. Все переменные имеют три атрибута:
               1. СЕГМЕНТ,  соответствующий  тому  сегменту,  который
                  ассемблировался, когда была определена переменная.
               2. СМЕЩЕНИЕ,  являющееся смещением данного поля памяти
                  относительно начала сегмента.
               3. ТИП,  определяющий  число  байтов,   подвергающихся
                  манипуляциям при работе с переменной.
               
               Метка  является   частным  случаем  переменной,  когда
         известно, что определяемая ею память содержит машинный  код.
         На  нее  можно ссылаться посредством скачков (переходов) или
         вызовов. Метка имеет два атрибута: СЕГМЕНТ и СМЕЩЕНИЕ. Метка
         также  может  быть  определена через другую метку директивой
         EQU.  
               Именами считаются символы, определенные директивой EQU
         и имеющие значением  символ  или  число.  Значения  имен  не
         фиксированы  в  процессе  ассемблирования, но при выполнении
         программы именам соответствуют константы. С переменными дело
         обстоит   наоборот   (если   значением   переменной  считать
         содержимое идентифицируемой ею области памяти). 
               Примеры имен:
               
         REGS   EQU   AX
         DIGIT  EQU   18
               
               Следующая директива определяет не имя:
               
         VARIABLE EQU   LB
               .............
         LB:      HLT
               
               Некоторые   идентификаторы,    называемые    ключевыми
         словами, имеют фиксированный смысл  и  должны  употребляться
         только в соответствии с этим. Ключевыми словами являются:
               1. Директивы ассемблера.
               2. Инструкции процессора.
               3. Имена регистров.
               4. Операторы выражений.
               
               Полный  список ключевых слов языка ассемблера приведен
         в Приложении 1.
               
               Следует помнить, что  обычно  ассемблер  не  различает
         строчные  и заглавные буквы, и идентификаторы могут включать
         в себя буквы обоих регистров. Например, идентификаторы AbS и
         abS  считаются  совпадающими.  Различие  между  строчными  и
         заглавными  буквами может быть установлено опциями /ML и /MX
         MASM, что может понадобиться, например, для совместимости  с

                                     -  8 -
         
         
         программами  на  регистро-чувствительных   языках   высокого
         уровня.
               
               
               
               
               
                             2.3. Типы данных.

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

               
               Синтаксис:
               
               цифры    
               цифрыB
               цифрыQ
               цифрыO
               цифрыD
               цифрыH
               
               Латинский символ, который может кодироваться на  обоих
         регистрах, задает основание счисления числа: B - двоичное, Q
         и O  -  8-ричное,  D  -  десятичное,  H  -  16-ричное.
               16-ричные  числа  не  должны  начинаться  с  буквенных
         16-ричных  цифр  (например, вместо некорректного ABh следует
         употреблять  0ABh).  16-ричные  цифры  от  A  до   F   могут
         кодироваться на обоих регистрах.
               Первая  форма  целого  числа  использует  умалчиваемое
         основание, которое может устанавливаться директивой  .RADIX.
         Если директива .RADIX не используется, полагается D.

               
               
               
               
               
                      2.3.2. Действительные числа.
               
               
               Синтаксис:

               цифрыR
               [[+|-]]цифры.цифры[[E[[+|-]]цифры]]

               Первый    формат    задает    16-ричное   кодированное

                                     -  9 -
         
         
         представление содержимого памяти, содержащей  действительное
         число.     Действительное     число    может    кодироваться
         последовательностью из 8, 12 или 20 16-ричных цифр (возможно
         добавление  предшествующих  0,  т.к.  первой   должна   быть
         десятичная   цифра).  Каждое  число  имеет  знак,  зависимую
         экспоненту и мантиссу, которые хранятся как поля бит в самом
         числе.  Точный  размер и смысл каждого бита зависит от числа
         бит в действительном числе.  
               Кодированные действительные числа могут использоваться
         в директивах DD, DQ и DT. Число 16-ричных цифр должно быть 8
         для  DD,  16  для DQ и 20 для DT (с предшествующим 0 - 9, 17
         или 21 соответственно). 
               Вторым  форматом  задается  действительное   число   с
         плавающей точкой. Цифры должны быть десятичными. Такие числа
         могут использоваться в директивах DD, DQ и DT.
               
               
               
               
               
                         2.3.3. Десятичные числа.
               
               
               Синтаксис:
               
               [[+|-]]цифры
               
               Этот вид соответствует упакованному формату десятичных
         чисел,  который включает в себя 1 знаковый байт и 9 значимых
         байтов.  Каждый  значимый  байт содержит 2 десятичные цифры.
         Допустимо кодирование до 18 включительно цифр.  Старший  бит
         знакового байта имеет значение 0 для положительных чисел и 1
         - для отрицательных.  
               Упакованные   десятичные    числа    имеют    то    же
         представление,  что  и  целые  десятичные числа (п.2.3.1) за
         исключением того, что они могут иметь знак и  использоваться
         только в директиве DT.

               
               
               
               
                    2.3.4. Знаковые и строковые константы.

               
               Синтаксис:
               
               'знаки'
               "знаки"
               
               Знаковая  константа  состоит  из одного знака алфавита
         языка.  Строковая  константа  включает  в  себя  2 или более
         знака. 
               В  отличие  от  других  компонент   языка,   строковые
         константы чувствительны к регистру.

                                     - 10 -
         
         
               Символы  '  и  "  в теле константы должны кодироваться
         дважды.
               
               
               
               
                              2.4. Предложения.
               
               
               Синтаксис:
               
               [[имя]] мнемоника [[операнды]][[;комментарии]]
               
               Предложения определяют структуру и функции  программы.
         Они  могут  начинаться  с любой позиции и содержать не более
         128 символов. 
               Предложение не может содержать внутри себя  комбинации
         символов   CARRIAGE-RETURN/LINE-FEED,  т.е.  не  может  быть
         продолжено на другую строку. Однако, все предложения,  кроме
         последнего, должны заканчиваться этой комбинацией символов.
               Все  предложения языка ассемблера делятся на директивы
         ассемблера и инструкции процессора.
               Директивы   ассемблера   действуют   лишь   в   период
         компиляции  программы  и  позволяют   устанавливать   режимы
         компиляции,   задавать   структуру   сегментации  программы,
         определять  содержимое  полей  данных,   управлять   печатью
         листинга программы, а также обеспечивают условную компиляцию
         и  некоторые другие функции. В результате обработки директив
         макроассемблером объектный код не генерируется.
               Инструкции процессора представляют собой мнемоническую
         форму  записи  машинных  команд, непосредственно выполняемых
         микропроцессором.   Все   инструкции   в   соответствии    с
         выполняемыми ими функциями делятся на 5 групп:
               1. Инструкции пересылки данных.
               2. Арифметические, логические и операции сдвига.
               3. Операции со строками.
               4. Инструкции передачи управления.
               5. Инструкции управления процессором.
               
               Подробнее  о  директивах  ассемблера   и   инструкциях
         процессора  см. "Система программирования на макроассемблере
         MS-DOS. Часть 3. Элементы языка ассемблера".
               
               
               
               
               
                              2.5. Комментарии.
               
               
               Часть строки исходного текста после символа ; (если он
         не  является элементом знаковой константы или строки знаков)
         считается комментарием и ассемблером игнорируется.
               Комментарии вносятся в программу как поясняющий  текст
         и  могут  содержать  любые  знаки  до  ближайшей  комбинации

                                     - 11 -
         
         
         символов CARRIAGE-RETURN/LINE-FEED, т.е. до конца строки. 
               Для создания комментариев, занимающих несколько строк,
         может быть использована директива COMMENT. 
                                         
                                     - 12 -
               
               
               
               
               
                 3. Регистры процессора и способы адресации.
               
               
               
               Семейство   микропроцессоров   8086/80186/80286  имеет
         одинаковый  набор  регистров  и  сходные  режимы   адресации
         памяти,  поэтому  для простоты изложения в настоящем разделе
         описываются регистры и адресация процессора 8088.
               Все   регистры   процессора   8088,   кроме   случаев,
         оговоренных особо, занимают 2 байта.
               Существуют 5 файлов регистров (Приложение 2):
               1. Регистры  общего  назначения:  AX, BX, CX и DX. Они
                  могут быть использованы  для  хранения  данных  или
                  элементов  адреса  в адресных выражениях. Каждый из
                  этих регистров можно рассматривать как совокупность
                  двух  регистров,  занимающих  его старший и младший
                  байты. Например, регистр AH соответствует  старшему
                  байту,  а регистр AL - младшему байту регистра AX и
                  т.п. как показано в Приложении 2.
               2. Регистры указателя: SP  и  BP.  Обычно  регистр  SP
                  используется  в операциях со стеком, а регистр BP -
                  как базовый регистр  в  адресных  выражениях  (что,
                  впрочем, не является обязательным).
               3. Индексные   регистры:   SI   и   DI.   Они   обычно
                  используются в операциях со строками для  адресации
                  источника (SI) и приемника (DI). 
               4. Регистры   сегмента:  CS,  DS,  SS  и  ES.  Условно
                  программа  на  языке  ассемблера  состоит  из   4-х
                  сегментов,   каждый  из  которых  адресуется  своим
                  регистром сегмента:
                  - сегмент  кода,  содержащий  инструкции  программы
                    (адресуется регистром CS);
                  - сегмент    данных,    содержащий     используемые
                    программой поля данных (адресуется регистром DS);
                  - сегмент  стека,  содержащий   стек   пользователя
                    (адресуется регистром SS);
                  - экстра  сегмент,  содержащий  данные,  общие  для
                    нескольких программ (адресуется регистром ES).
               5. Указатель  инструкции  (IP)  и  флаги.  Регистр  IP
                  вместе  с  регистром  CS,  если он используется для
                  адресации кода программы, используется  процессором
                  для выборки с целью исполнения очередной инструкции
                  программы.  Регистр  флагов  состоит  из   9   бит,
                  расположение   и  назначение  которых  показаны   в
                  Приложении 2. Значения флагов  отражают  результаты
                  выполнения  процессором машинных инструкций и могут
                  анализироваться, например,  инструкциями  условного
                  перехода.

                                     - 13 -
         
         
               
               Описанные выше назначения регистров не являются строго
         обязательными, но при отсутствии особых указаний принимаются
         по умолчанию и способствуют освобождению исходного текста от
         излишних спецификаций.
               Кроме того,  существуют еще несколько правил умолчания
         (с более низким приоритетом, чем у указанных выше):
               1. Регистр BP обычно  содержит  смещение  относительно
                  содержимого регистра SS.
               2. Регистры  BX,  SI  и  DI  обычно  содержат смещения
                  относительно содержимого регистра DS.
               3. Регистр DI всегда  содержит  смещение  относительно
                  содержимого  регистра  ES,  если  он используется в
                  инструкциях обработки строк.
               
               Полный   физический   адрес   памяти  процессора  8088
         содержит 20 бит, что позволяет адресовать 1М памяти.
               Процессор  8088  реализует  четырехкомпонентную  схему
         адресации   (см.   Приложение   2),   при   которой   полный
         20-разрядный адрес образуется из 4-х источников:
               1. Регистр сегмента.
               2. Базовый регистр.
               3. Индексный регистр.
               4. Непосредственное смещение.
               
               20-разрядный   физический   адрес   формируется  путем
         сложения   содержимого   одного   из   регистров   сегмента,
         умноженного  на  16  (для  получения  20-разрядного  числа),
         содержимого  базового  и  индексного  регистров,   а   также
         смещения, представленного целым числом в пределах  от  0  до
         65535.
               Поскольку  базовый  и  индексный  регистры  и смещение
         представляют собой 16-разрядные числа, они могут  адресовать
         память  в  пределах  64К  относительно  адреса,  задаваемого
         регистром сегмента.
               В  зависимости  от   спецификаций   и   местоположения
         источников  образования  полного  адреса  в языке ассемблера
         различают следующие способы адресации:
               1. Непосредственная,     когда     требуемые    данные
                  расположены непосредственно в команде,  а источники
                  образования адреса отсутствуют.
               2. Регистровая, когда данные расположены в регистре.
               3. Прямая,  когда в команде явно указан адрес сегмента
                  и смещение относительно его начала.
               4. Косвенная,  при   которой  присутствуют  один   или
                  несколько из указанных выше источников формирования
                  адреса.  Если   опущена    спецификация   смещения,
                  используется   смещение    0.     При    отсутствии
                  спецификации   какого-либо   регистра   применяются 
                  правила умолчания или, если это невозможно, регистр
                  не используется.
               
               Более  подробно способы кодирования адресных операндов
         описаны в п.4.1.
                                         
                                     - 14 -
               
               
               
               
               
                             4. Выражения.

               
               
               
               
               В языке ассемблера выражения могут быть использованы в
         инструкциях   или   директивах  и  состоят  из  операндов  и
         операторов. 
               Операнды представляют значения, регистры  или  позиции
         памяти,  используемые нужным образом по контексту программы.
         Они описаны в п.4.1.
               Операторы   выполняют   арифметические,    логические,
         побитовые   и  другие  операции  над  операндами  выражений.
         Операторы описаны в п.4.2.
               
               
               
               
               
                        4.1. Операнды выражений.
               
               
               Операнд выражения представляет собой константу, метку,
         переменную  или  другой символ, используемый в программе для
         представления значения, регистра или адреса памяти.
               Операнды бывают следующих типов:
               
               
               1. Константа. Синтаксис:
               
               число | строка | выражение
               
               Константой   считается   число,  строковая  константа,
         символ  или   выражение,   преобразуемое   в   фиксированное
         значение.   В   отличие   от   других  операндов,  константы
         представляют  значения,  используемые  в  выражениях  раньше
         (предпочтительней)  адресов  памяти.  Например,  в следующей
         инструкции 1 рассматривается ассемблером как число 1,  а  не
         как адрес памяти:
                     MOV AX,1
               Символ   считается   константой,   если  он  определен
         директивой EQU или оператором знакового равенства (=).
               
               
               2. Операнд прямой памяти. Синтаксис:
               
               сегмент : смещение

                                     - 15 -
         
         
               
               Операнд  прямой   памяти   реализует   прямой   способ
         адресации.  В качестве сегмента может использоваться регистр
         сегмента, имя сегмента или имя группы. Смещение лолжно  быть
         целым числом в пределах от 0 до 65535.
               Операнд  прямой  памяти  представляет абсолютный адрес
         памяти.
               
               
               3. Переместимый операнд. Синтаксис:
               
               символ
               
               Переместимый   операнд   представляет   адрес   памяти
         (сегмент  и  смещение). В отличие от операнда прямой памяти,
         переместимый операнд "привязан" к началу сегмента или группы
         и не имеет точного значения до обработки программы LINK.
               
               
               4. Указатель позиции. Синтаксис:
               
               $
               
               Этот  операнд  представляет  текущую позицию в текущем
         сегменте и имеет те же атрибуты, что и метка типа NEAR.
               
               
               5. Регистр (см. п.3).
               
               
               6. Базированный операнд. Синтаксис:
               
               смещение [BP]
               смещение [BX]
               
               Базированный  операнд  представляет  адрес  памяти  по
         отношению  к  содержимому  базового  регистра:  BP  или  BX.
               Смещением может  быть  непосредственное  значение  или
         операнд прямой памяти. Если смещение опущено, полагается 0. 
               Если  указан  регистр BP, физический адрес вычисляется
         относительно регистра SS, а если BX - относительно DS.
               Следующие   формы   записи   базированных    операндов
         эквивалентны:
               [смещение][BP]
               [BP+смещение]
               [BP].смещение
               [BP]+смещение
               
               
               7. Индексный операнд. Синтаксис:
               
               смещение [SI]
               смещение [DI]
               
               Индексный   операнд   представляет   адрес  памяти  по

                                     - 16 -
         
         
         отношению к содержимому индексного регистра: SI или DI. 
               Смещением может  быть  непосредственное  значение  или
         операнд прямой памяти. Если смещение опущено, полагается 0. 
               Физический адрес вычисляется относительно регистра DS.
               Следующие    формы    записи    индексных    операндов
         эквивалентны:
               [смещение][DI]
               [DI+смещение]
               [DI].смещение
               [DI]+смещение
               
               
               8. Базо-индексный операнд. Синтаксис:
               
               смещение [BP] [SI]
               смещение [BX] [DI]
               
               Базо-индексный   операнд   представляет  адрес  памяти
         относительно  суммы  содержимого   базового   и   индексного
         регистров. 
               Смещением может  быть  непосредственное  значение  или
         операнд прямой памяти. Если смещение опущено, полагается 0. 
               Если  указан  регистр BP, физический адрес вычисляется
         относительно регистра SS, а если BX - относительно DS.
               Следующие   формы   записи   базо-индексных  операндов
         эквиваленты:
               [смещение][BP][DI]
               [BP+DI+смещение]
               [BP+DI].смещение
               [DI]+смещение+[BP]
               Недопустимо лишь сочетание одновременно  двух  базовых
         или двух индексных регистров.
               
               
               9. Структура. Синтаксис:
               
               переменная.поле
               
               Этот   операнд   представляет   адрес   одного   члена
         структуры.  Переменная  должна  быть  именем  структуры  или
         операндом   памяти,   значением   которого   является  адрес
         структуры. Поле  должно  присутствовать  в  этой  структуре.
         Точка является оператором поля структуры (п.4.2).
               Адрес  вычисляется относительно сегмента или группы, в
         которых определена структура. 
               
               
               10. Запись. Синтаксис:
               
               имя-записи <[[значение]],...>
               
               Этот операнд ссылается к  значению  типа  запись.  Имя
         записи   должно   быть   определено  в  исходном  файле  как
         переменная типа запись директивой  RECORD.  В  скобках  <  >
         указываются  значения полей этой записи по порядку. Значения

                                     - 17 -
         
         
         могут включать в себя выражения и символы,  преобразуемые  в
         константы.   Если   значение  поля  опущено,  предполагается
         умалчиваемое значение для этого поля. 
               Значение этого операнда является константой.
               Пример:
         ENCODE RECORD HI:4,MID:3,LO:3
         REC1   ENCODE <3,2,1>
                MOV    AX,REC1
               Согласно объявлению запись ENCODE включает  в  себя  3
         поля   общей  длиной  10  бит.  После  выполнения  фрагмента
         содержимое регистра AX будет 0000000011010001b.
               
               
               11. Поле записи. Синтаксис:
               
               имя-поля-записи
               
               Этот операнд представляет позицию поля соответствующей
         записи.  Операнд  вычисляется  по  отношению к младшим битам
         поля и может быть использован только как константа. 
               Пример:
         ENCODE RECORD HI:4,MID:3,LO:3
         REC1   ENCODE <3,2,1>
                ...
                MOV    CL,HI      ; offset HI (6)  ->  CL
                MOV    DX,REC1
                ROR    DX,CL      ; rotate to right by 6
                MOV    REC1,DX
               Согласно объявлению запись ENCODE включает  в  себя  3
         поля   общей  длиной  10  бит.  После  выполнения  фрагмента
         содержимое поля REC1 будет 1111000000001001b.
               
               
               
               
               
                            4.2. Операторы.
               
               
               Ассемблер   обеспечивает   выполнение  арифметических,
         побитовых и  операторов  отношения,  позволяющих  различными
         способами манипулировать с операндами выражений. Кроме того,
         имеются  операторы  атрибутов,  выполняющие   действия   над
         атрибутами операндов. 
               В дополнение к этому для операций над операндами могут
         быть использованы оператор DUP и специальные макрооператоры,
         которые в настоящем руководстве не описываются.
               Ниже   даны   описания   используемых   в   выражениях
         операторов.
               
               
               1. Арифметические операторы. Синтаксис:
               
               выражение-1 * выражение-2
               выражение-1 / выражение-2

                                     - 18 -
         
         
               выражение-1 MOD выражение-2
               выражение-1 + выражение-2
               выражение-1 - выражение-2
               + выражение
               - выражение
               
               Эти   операторы   обеспечивают   выполнение   основных
         арифметических  действий.  Причем,  здесь  MOD  - остаток от
         деления выражения-1 на выражение-2, а знаком /  обозначается
         деление нацело. 
               Для  всех  операторов,  кроме  бинарных  +  и  -,  оба
         выражения должны быть целыми числами. Бинарные + и  -  могут
         быть   использованы   для   прибавления   к  (вычитания  от)
         переместимому операнду памяти целого числа. Бинарный - может
         использовать два переместимых операнда памяти, если значение
         выражения указывает в тот же сегмент. 
               Результатом   арифметического    оператора    является
         абсолютное значение.
               
               
               2. Операторы сдвига. Синтаксис:
               
               выражение SHR счетчик
               выражение SHL счетчик
               
               Операторы  SHR  и  SHL  сдвигают  значение   выражения
         соответственно   вправо   и   влево   на   число   разрядов,
         определяемое  счетчиком.   Биты,   сдвигаемые   за   пределы
         выражения,  теряются.  Если  значение счетчика превышает 15,
         результатом  выполнения  оператора  сдвига  будет  0,  когда
         значение   выражения   занимает   2  байта.  Если  значением
         выражения является 1 байт, для получения нулевого результата
         достаточен сдвиг на 8 разрядов.
               Не   следует   смешивать   операторы   SHR   и  SHL  с
         одноименными инструкциями процессора.
               
               
               3. Операторы отношений. Синтаксис:
               
               выражение-1 EQ выражение-2
               выражение-1 NE выражение-2
               выражение-1 LT выражение-2
               выражение-1 LE выражение-2
               выражение-1 GT выражение-2
               выражение-1 GE выражение-2
               
               Мнемонические    коды    отношений    расшифровываются
         следующим образом:
               EQ - равно
               NE - не равно
               LT - меньше
               LE - меньше или равно
               GT - больше
               GE - больше или равно
               Операторы  отношений  вырабатывают значение 0FFFFh при

                                     - 19 -
         
         
         выполнении условия и 0000h в противном случае. 
               Выражения должны иметь абсолютные значения.
               Операторы  EQ  и  NE  рассматривают свои аргументы как
         16-битовые числа. Поэтому, например, выражение -1 EQ  0FFFFh
         истинно, т.к. используется знаковый разряд (бит 15). 
               Остальные   операторы   трактуют  свои  аргументы  как
         17-битовые числа, в которых  старший  бит  определяет  знак.
         Поэтому  здесь  0FFFFh - не -1, а максимальное положительное
         число - 65535.
               Операторы отношений обычно используются  в  директивах
         условного ассемблирования и инструкциях условного перехода.
               
               
               4. Операции с битами. Синтаксис:
               
               NOT выражение
               выражение-1 AND выражение-2
               выражение-1 OR выражение-2
               выражение-1 XOR выражение-2
               
               Мнемоники операций расшифровываются следующим образом:
               NOT - инверсия
               AND - логическое И
               OR  - логическое ИЛИ
               XOR - исключающее логическое ИЛИ
               Операции  выполняются  над   каждыми   соотвествующими
         битами выражений. Выражения должны иметь абсолютные значения.
               
               
               5. Оператор индекса. Синтаксис:
               
               [[выражение-1]] [выражение-2]
               
               Оператор  индекса  []  складывает  указанные выражения
         подобно тому, как это делает оператор +, с той разницей, что
         первое выражение необязательно.
               Выражение-1   может   быть  целым  числом,  абсолютным
         символом или  переместимым  операндом.  При  его  отсутствии
         предполагается  0.  Если  выражение-1  является переместимым
         операндом,   выражение-2   должно   быть  целым  числом  или
         абсолютным  символом.  В  противном случае выражение-2 может
         быть, кроме того, еще и переместимым операндом.
               
               
               
               6. Оператор PTR:
               
               тип PTR выражение
               
               При  помощи  оператора  PTR  переменная   или   метка,
         задаваемая выражением, может трактоваться как переменная или
         метка указанного типа.
               Тип может быть  задан  одним  из  следующих  имен  или
         значений:
               

                                     - 20 -
         
         
               Имя типа              Значение
               --------              --------
               BYTE                     1
               WORD                     2
               DWORD                    4
               QWORD                    8
               TBYTE                   10
               NEAR                   0FFFFh
               FAR                    0FFFEh
               
               Выражение может включать в себя любые операнды.
               Типы  BYTE,  WORD,  DWORD,  QWORD  и  TWORD могут быть
         использованы только с операндами памяти, а типы NEAR и FAR -
         только с метками.
               Оператор   PTR   обычно   используется   для   точного
         определения размера, или расстояния,  ссылки.  Если  PTR  не
         используется,   ассемблер   подразумевает  умалчиваемый  тип
         ссылки.  Кроме   того,   оператор   PTR   используется   для
         организации   доступа   к  объекту,   который    при  другом
         способе вызвал  бы генерацию сообщения об ошибке  (например,
         для доступа к старшему байту переменной размера WORD). 
               В  п.4.3  обсуждается,  как  оператор  PTR  может быть
         использован для того, чтобы избежать  ошибок,  связанных  со
         строгим контролем типов.
               
               
               7. Оператор переключения сегментов. Синтаксис:
               
               регистр-сегмента : выражение
               имя-сегмента : выражение
               имя-группы : выражение
               
               Оператор   переключения   сегмента   (:)  обеспечивает
         вычисление адреса данной переменной или  метки  относительно
         содержимого  указанного  регистра  сегмента, начала сегмента
         или начала группы. Если задано имя сегмента или имя  группы,
         это   имя  должно  быть  предварительно  присвоено  регистру
         сегмента директивой ASSUME и определено в директивах SEGMENT
         или GROUP. 
               Выражение   может   быть   абсолютным   символом   или
         переместимым операндом.
               По  умолчанию  физический   адрес   операндов   памяти
         вычисляется  относительно  содержимого  регистров CS, DS, SS
         или ES в зависимости от  инструкции  и  типа  операнда.  Все
         метки  по  умолчанию  понимаются  как NEAR. Эти умалчиваемые
         действия при необходимости могут  быть  изменены  оператором
         переключения сегмента. 
               
               
               8. Оператор имени поля структуры. Синтаксис:

               
               переменная.поле
               
               Этот  оператор (.) используется для обозначения поля в

                                     - 21 -
         
         
         переменной  типа  структура.  Оператор  эквивалентен   +   в
         базированных и индексных операндах.
               
               
               9. Оператор SHORT :
               
               SHORT метка
               
               Этот  оператор  присваивает указанной метке тип SHORT.
         Такая метка может быть использована  в  инструкции  JMP  для
         передачи управления не далее, чем на 127 байтов. Инструкции,
         использующие  короткие  метки типа SHORT, требуют для своего
         размещения на 1 байт меньше.
               
               
               10. Оператор THIS :
               
               THIS тип
               
               Этот оператор порождает операнд с атрибутами СЕГМЕНТ и
         СМЕЩЕНИЕ,   соответствующими   текущему  значению  указателя
         позиции, и специфицированным типом. В  качестве  типа  могут
         кодироваться BYTE, WORD, DWORD, QWORD, TBYTE, NEAR или FAR.
               Оператор THIS обычно используется вместе с директивами
         EQU или знакового  равенства  (=)  для  порождения  меток  и
         переменных  (подобно  использованию для этих целей директивы
         LABEL). 
               Примеры:
         TAG   EQU  THIS BYTE
         CHECK =    THIS NEAR
               
               
               11. Операторы HIGH и LOW :
               
               HIGH выражение
               LOW выражение
               
               Операторы HIGH и LOW вычисляют  соответственно старшие
         и  младшие 8 битов значения выражения. Выражение может иметь
         любое значение.
               
               
               12. Оператор SEG :
               
               SEG выражение
               
               Этот оператор  вычисляет   значение  атрибута  СЕГМЕНТ
         выражения.  Выражение  может быть меткой. переменной, именем
         сегмента, именем группы или другим символом.
               
               
               13. Оператор OFFSET :
               
               OFFSET выражение
               

                                     - 22 -
         
         
               Этот оператор  вычисляет  значение  атрибута  СМЕЩЕНИЕ
         выражения.  Выражение  может быть меткой, переменной, именем
         сегмента или другим символом. Для имени сегмента вычисляется
         смещение    от   начала   этого   сегмента   до   последнего
         сгенерированного в этом сегменте байта. 
               При использовании оператора переключения сегмента  (:)
         оператор  OFFSET  вычисляет  число  байтов  между  элементом
         выражения и началом указанного  сегмента  или  группы.  Этим
         способом   можно   генерировать   допустимые   смещения  для
         элементов группы. 
               
               
               14. Оператор TYPE :
               
               TYPE выражение
               
               Оператор  TYPE  порождает  число,  представляющее  тип
         выражения.  Если  выражение  является  переменной,  оператор
         вычисляет  размер  переменной  в  байтах.   Если   выражение
         является  меткой,  оператор  формирует  значение  0FFFFh для
         метки типа NEAR и 0FFFEh для  метки  типа  FAR.  Вычисляемое
         значение   может   быть   использовано  для  спецификации  в
         операторе PTR, например:
               JMP (TYPE get_loc) PTR destiny
               
               
               15. Оператор .TYPE :
               
               .TYPE выражение
               
               Этот оператор формирует 1 байт, определяющий  режим  и
         сферу  выражения. Если выражение некорректно, все биты этого
         байта  равны  0.  Возможные  значения  битов   приведены   в
         следующей таблице:
               
         ____________________________________________________________
         |     |                        |                           |
         | бит |           0            |            1              |
         |_____|________________________|___________________________|
         |     |                        |                           |
         |  0  | не связано с программой|   связано с программой    |
         |_____|________________________|___________________________|
         |     |                        |                           |
         |  1  |  не связано с данными  |    связано с данными      |
         |_____|________________________|___________________________|
         |     |                        |                           |
         |  5  |     не определено      |         определено        |
         |_____|________________________|___________________________|
         |     |                        |                           |
         |  7  |  локальная или общая   |   внешняя сфера (EXTRN)   |
         |     |    сфера (PUBLIC)      |                           |
         |_____|________________________|___________________________|
         
               Остальные биты результирующего байта всегда равны 0.
               Оператор  .TYPE   обычно   используется   в   условных

                                     - 23 -
         
         
         директивах. 
         
         
               16. Оператор LENGTH :
         
               LENGTH переменная
         
               Этот  оператор  вычисляет  число  элементов типа BYTE,
         WORD,  DWORD  или  TBYTE  для переменной. Выбираемый элемент
         зависит от типа переменной.
               Только для переменных,  определенных  оператором  DUP,
         оператор  LENGTH  формирует значения, большие 1. Формируемое
         число  всегда  определяется  первым из операторов DUP  и  не
         зависит от их вложенности. 
               Пример:
         ARRAY DW 100 DUP(1)
         TABLE DW 100 DUP(1,10 DUP(?))
               ...
               MOV CX,LENGTH ARRAY ; load 100
               MOV CX,LENGTH TABLE ; load 100
               
               
               17. Оператор SIZE :
               
               SIZE переменная
               
               Оператор   SIZE   определяет   число   байтов  памяти,
         выделенных переменной. Оператор SIZE можно рассматривать как
         комбинацию операторов LENGTH и TYPE.
               
               
               18. Оператор WIDTH :
               
               WIDTH имя-поля-записи | запись
               
               Этот оператор вычисляет длину записи или поля записи в
         битах.
               
               
               19. Оператор MASK :
               
               MASK имя-поля-записи | запись
               
               Этот оператор формирует маску битов для  представления
         позиций  заданного поля в записи. Бит маски равен 1, если он
         соответствует биту поля, и 0 - в противном случае.
               Пример:
         RTYPE RECORD F1:3,F2:6,F3:7
               ...
               M1=MASK F1  ; 11100000 00000000b
               M2=MASK F2  ; 111111000000b
               M3=MASK F3  ; 1111111b
               M=MASK RTYPE ; 0FFh
               
               

                                     - 24 -
         
         
               
               
               
               
                    4.3. Особенности вычисления выражений.
               
               
               
                       4.3.1. Приоритеты операций.
               
               
               При вычислении значения выражения операции выполняются
         в  соответствии  со следующим списком приоритетов (в порядке
         убывания):
               1. LENGTH, SIZE, WIDTH, MASK, (), [], <>.
               2. Оператор имени поля структуры (.).
               3. Оператор переключения сегмента (:).
               4. PTR, OFFSET, SEG, TYPE, THIS.
               5. HIGH, LOW.
               6. Унарные + и -.
               7. *, /, MOD, SHR, SHL.
               8. Бинарные + и -.
               9. EQ, NE, LT, LE, GT, GE.
               10. NOT.
               11. AND.
               12. OR, XOR.
               13. SHORT, .TYPE.
               
               
               
               
                        4.3.2. Ссылки вперед.

               
               Хотя ассемблер  и  допускает  ссылки  вперед  (т.е.  к
         еще  необъявленным  объектам  программы), такие ссылки могут
         при неправильном использовании приводить к ошибкам.
               Пример ссылки вперед:
               JMP TARGET
               ...
         TARGET: ...
               
               Всякий    раз,    когда     ассемблер     обнаруживает
         неопределенное  имя на 1-м проходе, он предполагает, что это
         ссылка вперед. Если указано  только  имя,  ассемблер  делает
         предположения о его типе и используемом регистре сегмента, в
         соответствии с которыми и генерируется  код.  В  приведенном
         выше  примере предполагается, что TARGET - метка типа NEAR и
         для ее адресации используется регистр CS, в результате  чего
         генерируется  инструкция  JMP,  занимающая 3 байта. Если бы,
         скажем,  в  действительности  тип   ссылки   оказался   FAR,
         ассемблеру нужно было бы генерировать 5-байтовую инструкцию,
         что уже невозможно, и формировалось бы сообщение об ошибке.
               Во   избежание   подобных    ситуаций    рекомендуется
         придерживаться следующих правил:

                                     - 25 -
         
         
               1. Если ссылка вперед является переменной, вычисляемой
                  относительно  регистров  ES,  SS  или  CS,  следует
                  использовать  оператор  переключения сегмента. Если
                  он  не  использован,  делается  попытка  вычисления
                  адреса относительно регистра DS.
               2. Если ссылка вперед  является  меткой  инструкции  в
                  команде  JMP и отстоит не далее, чем на 128 байтов,
                  можно использовать оператор SHORT.  Если  этого  не
                  делать,  метке  будет  присвоен  тип  FAR,  что  не
                  вызовет ошибки, но на  2-м  проходе  ассемблер  для
                  сокращения  размера  содержащей  ссылку  инструкции
                  вынужден будет вставить дополнительную  и  ненужную
                  инструкцию NOP.
               3. Если  ссылка  вперед  является  меткой инструкции в
                  командах  CALL  или   JMP,   следует   использовать
                  оператор  PTR  для  определения  типа  метки. Иначе
                  ассемблер  устанавливает  тип  NEAR,  и,   если   в
                  действительности  тип  метки  окажется  FAR,  будет
                  выдано сообщение об ошибке.
               4. Если  ссылка  вперед  является  именем  сегмента  с
                  оператором   переключения   сегмента   (:),   можно
                  использовать  директиву  GROUP  для   связи   имени
                  сегмента  с  именем  группы,  а  затем использовать
                  директиву ASSUME для связи имени группы с регистром
                  сегмента. Пример:
                  DGROUP GROUP STACK
                         ASSUME SS:DGROUP
                  CODE:  SEGMENT 
                         ...
                         MOV AX, STACK:STACKTOP
                  Если  имя  сегмента не связано с группой, ассемблер
                  может   игнорировать   переключение   сегмента    и
                  использовать  умалчиваемый  регистр  сегмента,  что
                  обычно приводит к ошибкам на 2-м проходе.
                  
               
               
               
               
                         4.3.3. Контроль типов.

               
               Ассемблер выполняет  строгий  синтаксический  контроль
         инструкций,  включающий  проверку  точного кодирования типов
         операндов памяти. Любой переместимый операнд, используемый в
         инструкции,   которая   оперирует   с   данными   некоторого
         предполагаемого типа, должен либо иметь  тот  же  тип,  либо
         предусматривать преобразование типа оператором PTR.
               Пример некорректного кодирования:
         STRING DB  "A MESSAGE"
                ...
                MOV AX,STRING[1]
               Пример правильного кодирования:
                ...
                MOV AX, WORD PTR STRING[1]

                                     - 26 -
                                     
                                     
                  Приложение 1. Ключевые слова языка ассемблера.
                
         .186      DI        .ERRNZ    LENGTH    .SALL
         .286c     DL        ES        .LFCOND   SEG
         .286p     DQ        EVEN      .LIST     SEGMENT
         .287      DS        EXITM     LOCAL     .SFCOND
         .8086     DT        EXTRN     LOW       SHL
         .8087     DW        FAR       LT        SHORT
         =         DWORD     GE        MACRO     SHR
         AH        DX        GROUP     MASK      SI
         AL        ELSE      GT        MOD       SIZE
         AND       END       HIGH      NAME      SP
         ASSUME    ENDIF     IF        NE        SS
         AX        ENDM      IF1       NEAR      STRUC
         BH        ENDP      IF2       NOT       SUBTTL
         BL        ENDS      IFB       OFFSET    TBYTE
         BP        EQ        IFDEF     OR        .TFCOND
         BX        EQU       IFDIF     ORG       THIS
         BYTE      .ERR      IFE       %OUT      TITLE
         CH        .ERR1     IFIDN     PAGE      TYPE
         CL        .ERR2     IFNB      PROC      .TYPE
         COMMENT   .ERRB     IFNDEF    PTR       WIDTH
         .CREF     .ERRDEF   INCLUDE   PUBLIC    WORD
         CS        .ERRDIF   IRP       PURGE     .XALL
         CX        .ERRE     IRPC      QWORD     .XCREF
         DB        .ERRIDN   LABEL     .RADIX    .XLIST
         DD        .ERRNB    .LALL     RECORD    XOR
         DH        .ERRNDEF  LE        REPT
         MOV       PUSH      PUSHF     POP       POPF
         XCHG      XLAT      LEA       LDS       LES
         LAHF      SAHF      IN        OUT       ADD
         ADC       INC       AAA       DAA       SUB 
         SBB       DEC       NEG       CMP       AAS
         DAS       MUL       IMUL      AAM       DIV
         IDIV      AAD       CBW       CWD       NOT
         AND       OR        XOR       TEST      RCL
         RCR       SAL       SAR       ROL       ROR
         MOVS      MOVSB     CMPS      CMPSB     CMPSW
         SCAS      SCASB     SCASW     LODS      STOS
         STOSB     STOSW     JA        JNBE      JAE
         JNB       JB        JNAE      JC        JE
         JZ        JG        JNLE      JGE       JNL
         JL        JNGE      JLE       JNG       JMP
         JNC       JNE       JNZ       JNO       JNP
         JPO       JNS       JO        JP        JPE
         JS        JCXZ      CALL      RET       LOOP
         LOOPE     LOOPZ     LOOPNE    LOOPNZ    REP
         REPE      REPZ      REPNE     REPNZ     INT3
         INT       INTO      IRET      STC       CLC
         CMC       STD       CLD       STI       CLI
         HLT       WAIT      ESC       LOCK      NOP
                                        
                                     - 27 -
                                     
                                     
                                     
                                     
                 Приложение 2. Регистры и адресация 
                               процессора 8088.
                    
                    
                    
                    
                    
           15                    8 7                     0
          _________________________________________________
          |                       |                       |
   AX     |          AH           |          AL           |
          |_______________________|_______________________|
          |                       |                       |
   BX     |          BH           |          BL           |
          |_______________________|_______________________| Регистры данных
          |                       |                       |
   CX     |          CH           |          CL           |
          |_______________________|_______________________|
          |                       |                       |
   DX     |          DH           |          DL           |
          |_______________________|_______________________|




           15                                            0
          _________________________________________________
указатель |                                               |
стека     |                      SP                       |
          |_______________________________________________| Регистры указателя
указатель |                                               |
базы      |                      BP                       |
          |_______________________________________________|




           15                                            0
          ________________________________________________
          |                                               |
источник  |                      SI                       |
          |_______________________________________________| Индексные регистры
          |                                               |
приемник  |                      DI                       |
          |_______________________________________________|
              
              
              
             

                                     - 28 -
         
         
              
           15                                            0
          _________________________________________________
          |                                               |
код       |                      CS                       |
          |_______________________________________________|
          |                                               |
данные    |                      DS                       |
          |_______________________________________________| Регистры сегментов
          |                                               |
стек      |                      SS                       |
          |_______________________________________________|
          |                                               |
экстра    |                      ES                       |
          |_______________________________________________|




           15                                            0
          _________________________________________________
          |                                               |
          |                      IP                       | Указатель команды
          |_______________________________________________|
          |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
          |  |  |  |  | O| D| I| T| S| Z|  | A|  | P|  | C| Флаги
          |__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|__|
          
                       11 10  9  8  7  6     4     2     0


          OF - переполнение                 ZF - нуль
          DF - флаг направления             AF - вспомогательный перенос
          IF - разрешение прерывания        PF - паритет
          TF - ловушка                      CF - перенос
          SF - знак




















                                     - 29 -
         
         

                         Условные обозначения:


                         B         - базовый регистр
                         X         - индексный регистр
                         S         - смещение
                         (...)     - содержимое регистра
                         ИА        - исполнительный 16-разрядный адрес
                         ЛА        - логический 16-разрядный адрес
                         ФА        - физический 20-разрядный адрес
                         [...]     - компонента может отсутствовать
                         {...|...} - обязательный выбор варианта
                         
          __________________________________________________
          |                     |                          |
          |   Типы адресации    |   Местоположение данных  |
          |_____________________|__________________________|
          |                     |                          |
          | 1. Непосредственная |      В команде           |
          |_____________________|__________________________|
          |                     |                          |
          | 2. Регистровая      |      В регистре          |
          |_____________________|__________________________|
          |                     |                          |
          | 3. Прямая           |      ИА - в команде      |
          |_____________________|__________________________|
          |                     |                          |
          | 4. Косвенная        |      ИА=(B)+[(X)]+[S]    |
          |_____________________|__________________________|
          
          
          
          ЛА = ИА данных | (IP) инструкции процессора | (SP) элемента стека
               | (SI) строки-источника | (DI) строки-приемника
           
             
          ФА = ЛА +  { (CS) | (DS) | (SS) | (ES) } * 16


© KOAP Open Portal 2000