 2.6 Встроенный ассемблер

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

     Примеры  обоих  случаев  дает  сама  форт-система.  Очевидно, что слова,
 выполняющие   арифметические   операции   или  действия  с  вершиной  стека,
 естественно   реализовывать   непосредственно  в  машинном  коде,  поскольку
 скорость  их  исполнения  в  значительной  степени определяет быстродействие
 системы. Вместе с тем слово 1+, увеличивающее на единицу значение на вершине
 стека, можно определить как в машинном коде (особенно если в данной ЭВМ есть
 специальная команда увеличения значения на единицу), так и через двоеточие:

          : 1+   ( A ---> A+1 )  1  +  ;

     В  последнем случае, если к тому же слово 1 реализовано в виде отдельной
 словарной  статьи 1 CONSTANT 1, шитый код займет всего три ячейки, что может
 быть  короче  аналогичной  программы  в  машинном коде. Разумеется, при этом
 исполнение  будет  дольше  за  счет интерпретации последовательности из трех
 ссылок  вместо  прямого  исполнения  соответствующих  машинных команд. Также
 очевидно,  что,  например,  форт-слова  для  обмена с терминалом естественно
 задать  на  машинном  уровне  через  обращения  к  соответствующим  функциям
 операционной системы или непосредственно к аппаратуре.

     Для определения слов непосредственно в машинном коде стандарт языка Форт
 предусматривает следующие слова:

          ASSEMBLER  --->
          CODE       --->
          END-CODE   --->
          ;CODE      ---> (компиляция)

 составляющие стандартное ассемблерное расширение обязательного набора слов.

     Слово  ASSEMBLER  (ассемблер)  является  именем списка слов, содержащего
 слова,  с  помощью которых строится машинный код (мнемоники машинных команд,
 обозначения регистров, способы адресации и т.д.).

     Слово  CODE (код) является определяющим для слов нижнего уровня и обычно
 определяется так:

          : CODE  ( ---> )
            CREATE  HERE  LATEST  NAME>  !  ASSEMBLER  ;

 Оно  используется  в  сочетании  со  словом END-CODE (конец кода): CODE<имя>
 <машинный-код>  END-CODE,  где  "имя" является именем определяемого слова, а
 "машинный-код"  -  записью  его  реализации в машинном коде в соответствии с
 принятыми соглашениями.

     Поле  кода  такой  словарной статьи содержит адрес ее поля параметров, в
 котором располагается данный машинный код.

     Наконец, слово ;CODE, имеющее признак немедленного исполнения, позволяет
 задавать  исполняющую  часть  определяющих  слов  непосредственно в машинном
 коде:

          : ;CODE ( ---> )  COMPILE  (;CODE)
            [COMPILE] [ ASSEMBLER ; IMMEDIATE

 Оно  используется внутри определения через двоеточие для определяющего слова
 аналогично слову DOES>

          : <имя>  <создающая-часть>
                      ;CODE  <машинный-код>  END-CODE

 и  отделяет высокоуровневую создающую часть от исполняющей части, заданной в
 машинном  коде.  Во  время  исполнения  скомпилированного словом ;CODE слова
 (;CODE)  адрес  машинной  программы,  составляющей  исполняющую часть, будет
 заслан  в  поле  кода  определяемого  слова,  которое  таким образом получит
 интерпретатор,  реализованный  в  машинном  коде.  На  практике именно таким
 способом задают стандартные определяющие слова :, CONSTANT и VARIABLE.

     Конкретный  вид  машинной  программы  зависит от архитектуры данной ЭВМ.
 Общим   правилом   является   то,   что   этот   текст   представляет  собой
 последовательность  слов,  которые  исполняются текстовым интерпретатором, в
 результате  чего  на  вершине  словаря  формируется соответствующий двоичный
 машинный  код.  Машинные  команды  записываются  в  естественной  для  Форта
 обратной  польской  форме:  сначала  операнды,  а  затем слово, обозначающее
 мнемонику команды.

     Операнды  - это слова, вычисляющие на стеке размещения операндов: номера
 регистров,  адреса  в  памяти  и  их  модификации, значения непосредственных
 операндов и т.д.

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

     Включение  запятой  в  имя  слова  для  кода  команды,  с одной стороны,
 подчеркивает  тот  факт,  что  данное  слово компилирует команду, а с другой
 стороны, позволяет отличать, например, часто встречающиеся мнемоники ADD, СН
 и т.д. от чисел, заданных в шестнадцатиричной системе.

     В   табл.  2.1  приведена  запись  одних  и  тех  же  машинных  команд в
 традиционном  ассемблере  и  встроенном  ассемблере  разных  форт-систем для
 нескольких  распространенных  типов  ЭВМ. Как и в случае реализации структур
 управления,  во  встроенный ассемблер можно включить дополнительные средства
 контроля,  которые,  учитывая формат машинных команд, проверяют правильность
 задания их операндов.

     Таблица   2.1.  Сравнительная  запись  машинных  команд  в  традиционном
 ассемблере и встроенном ассемблере форт-системы
  ┌─────────┬─────────────────────────┬───────────────────────────────────┐
  │ Тип ЭВМ │  Традиционный ассемблер │ Встроенный ассемблер форт-системы │
  ├─────────┼─────────────────────────┼───────────────────────────────────┤
  │  СМ-4   │  CMPB #12, (R1)+        │  12# R1 )+ CMPB,                  │
  │         │  JMP   NEXT             │  NEXT   JMP,                      │
  │         │  RTS                    │  RTS,                             │
  ├─────────┼─────────────────────────┼───────────────────────────────────┤
  │ ЕС ЭВМ  │  STM   14,12,12(13)     │  14 12 12 (, 13 STM,              │
  │         │  BALR   15, 0           │  15 0 BALR,                       │
  │         │  B     NEXT             │  NEXT B,                          │
  ├─────────┼─────────────────────────┼───────────────────────────────────┤
  │         │  MOV A, B               │  A B MOV,                         │
  │  К580   │  LXI H, 15              │  H 15 LXI,                        │
  │         │  POP H                  │  H POP,                           │
  ├─────────┼─────────────────────────┼───────────────────────────────────┤
  │         │  , UTC, =15             │  0 0 5 # # UTC,                   │
  │ БЭСМ-6  │  . XTA,                 │  0 0 XTA,                         │
  │         │  3, UTC, 777            │  3 777 UTC,                       │
  └─────────┴─────────────────────────┴───────────────────────────────────┘

     В  гл.  3  рассмотрена  реализация  полного  встроенного  ассемблера для
 микропроцессора К580, занимающая 100 строк текста на языке Форт.

     Встроенный   ассемблер  форт-систем  часто  делают  "структурным",  т.е.
 включают  в  него  операторы  ветвления  и  циклы,  выполняющие  переходы по
 значению  управляющих  разрядов в специальном регистре. По аналогии с такими
 же  средствами  языка  Форт  эти  структуры  задают  с помощью тех же слов с
 добавлением,  запятой:  IF,  THEN, ELSE, BEGIN, UNTIL и т.д. При этом вводят
 слова,  обозначающие  различные  состояния  управляющих  сигналов,  а слова,
 реализующие    структурные    операторы   компилируют   команды   переходов,
 соответствующие  указанным  состояниям.  Такой  подход  позволяет  во многих
 случаях  избежать  введения сложного механизма переходов на метку, поскольку
 ассемблерные   вставки,  для  трансляции  которых  и  существует  встроенный
 ассемблер, состоят, как правило, из нескольких команд.

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

     В  общем  объеме  больших программ на Форте ассемблерные коды составляют
 незначительную часть (в реализации самой форт-системы, например, 10-30%), но
 вместе  с  тем такая возможность делает программиста максимально свободным в
 выборе средств для реализации своих идей.

