Ремонт принтеров, сканнеров, факсов и остальной офисной техники


назад Оглавление вперед




[10]

GENERAL-OP

( <базовый опкод> -- )

D0ES>

\ \ \ \

( <операнд> -- ) получить базовый опкод добавляем "магическое число ассемблируем опкод

MODE @ CASE

0x00 OF С, ENDOF \ операнд байт

0x10 0F С, ENDOF \ операнд байт

0x30 OF , END0F \ операнд слово (2 байта) ENDCASE

RESET \ выбор режима адресации по умолчанию 8В GENERAL-OP ADD,

Каждый экземпляр GENERAL-OP будет иметь различный базовый опкод. Когда ADD, выполняется, он будет получать этот базовый опкод, добавлять к нему значение MODE, и комплировать полученный байт. Дале он будет брать операнд, находящийся на стеке, и компилировать его в зависимости от выбранного режима адресации как байт или слово. В конце MODE будет сброшен в значение по умолчанию. Отметим что уже определен весь код, который нужно использовать для определения инструкций того же семейства что и ADD:

0x89 GENERAL-OP ADC, 0x84 GENERAL-OP AND, 0x85 GENERAL-OP BIT,

Сохранение памяти при использовании определяющих слов по сравнению с обучными словами определенными через двоеточие очевидно. Все команды ассемблера, приведенные выше, используют единственный блок кода после DOES>, вызов которого из этих слов занимает всего несколько байт.

На самом деле это не мой код реального ассемблера 6809 - существуют дополнительные особые случаи, которые необходимо реализовать. Но он показывает что сохраняя что достаточно сделать чтобы сохранить информацию о режиме и как свободно использовать конструкцию CASE чтобы реализовать наиболее простые наборы команд.

6.3.7 Реализация структур управления

Структурное программирование наделало очень много шума, и было написано множество макропакетов "структурного ассемблирования"для распространенных ассемблеров. Но ФОРТ-ассемблерам изначально присущи такие свойства как отсутствие меток, структурный ассемблерный код, что объяснятся той причиной что на ФОРТ е проще реализовать структурный ассемблер чем метки.

Структуры, обычно включаемые в ФОРТ-ассемблеры, аналогичны структурам высокоуровневого ФОРТ а. Для их отличия к ним добавляется запятая, как это было сделано для ассемблерных команд.

Эта самая простая для понимания ассемблерная структура. Ассемблерный код должен защиклиться до метки BEGIN до того как будет удовлетворено некоторое условие. Синтаксис для ФОРТ-ассемблера:

6.3.8 BEGIN, UNTIL,


BEGIN, <код> <условие> UNTIL,

Код условия предположительно определен как операнд или режим адресации для инт-срукции перехода.

Очевидно что UNTIL должен комплировать условный переход. Условия перехода должны быть инвертированы так что если условие удовлетворяется, то переход игнорируется, в отличие от перехода когда условие ложно. Ассемблерный код для обычного ассемблера должен иметь вид:

ххх: ...

JR ~сс,ххх \ ~сс то же что и NOT(cc)

Существует два свойства, помогающие реализовать эту струткуру. Слово HERE22 возвращает текущий указатель компиляции. Числа могут храниться на стеке не влияя на реботу ФОРТ а, и доставаться по необходимости.

Итак BEGIN, должен запоминать позицию указателя компиляции помещая ее в стек, a UNTIL, будет ассемблировать условный переход по запомненному на стеке адресу.

: BEGIN, ( -- а )HERE ;

: UNTIL, ( а сс -- )NOTCC JR, ; \ флаг перехода инвертируется

Как видно по стековой нотации BEGIN, оставляет на стеке текущий адрес, и UNTIL, использует запомненный адрес и код условия для компиляции условного перехода. Слово NOTCC предварительно инвертирует код условия. Слово JR, использует адрес перехода и (инвертированный) код условия для формирования соответствущего кода условного перехода 6809.

Такая реализация позволяет использовать вложенные условные циклы:

сс UNTIL, сс UNTIL,

Вложенный UNTIL, ссылается на вложенный BEGIN,, формируая код цикла внутри кода охватывающего цикла.

6.3.9 BEGIN, AGAIN,

ФОРТ также поддерживает конструкцию бесконечного цикла BEGIN AGAIN. Определение этой конструкции для ассемблера аналогично, за тем исключением что код условия не используется, и компилируется безуслоный переход на начало цикла.

22THERE для при целевой компиляции

версия 26 октября 2005 г.ФОРТ


6.3.10DO, LOOP,

Многие процессоры предоставляют некоторые инструкции цикла. Так как их нет у 6809, расмотрим Zilog Super8. Он имеет инструкцию DJNZ (декремент и переход если не ноль), которая может использовать любой из 16 регистров как счетчик цикла. Для процессора 80x86 эта инструкция работает только с регистром (Е)СХ. Цикл на структурном ассемблере будет иметь вид:

DO, ... г LOOP,

где г регистр используемый как счетчик цикла.

: DO, ( -- a)HERE ;

: LOOP, ( а г -- ) DJNZ, ;

В некоторых ФОРТ-ассемблерах DO, также ассемблирует код инициализации счетчика цикла, но это уменьшает гибкость.

6.3.11IF, THEN,

Эта конструкция - простейшая конструкция, использующая ссылки вперед. Если условие истинно, она должна выполняться, иначе управление передается на первую инструкцию после THEN,.

Ассемблерный код для ФОРТ-синтаксиса

сс IF, ......... THEN,

будет иметь вид JP ~сс,ххх

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

В однопроходном ассемблере необходимый переход вперед не может быть скомпилирован сразу, так как адрес перехода еще неизвестен. Эта проблема решается путем ассемблирования пустого перехода типа JMP 0 и помещения на стек адреса операнда команды JMP. Позже слово THEN, сможет взять этот адрес и пропатчить скомплирированный JMP, соответствующм образом модифицировав его операнд.

: IF, (сс -- а)

NOT 0 SWAP JP,\ условный переход

HERE 2 -\ помещаем на стек HERE-<pa3Mep операнда>

: THEN, (а --)

HERE SWAP !\ запоминаем по адресу операнда JP текущий



[стр.Начало] [стр.1] [стр.2] [стр.3] [стр.4] [стр.5] [стр.6] [стр.7] [стр.8] [стр.9] [стр.10] [стр.11] [стр.12] [стр.13] [стр.14] [стр.15]