Адресный интерпретатор: различия между версиями

Материал из ПМК вики
Перейти к навигации Перейти к поиску
(не показано 17 промежуточных версий этого же участника)
Строка 15: Строка 15:


== Реализация ==
== Реализация ==
В [[Каллисто|Каллисто 1.0]] адресный интерпретатор способен исполнять [[шитый код]] как из [[Регистры байтовых данных|памяти данных]], так и из [[Память программ|памяти программ]] [[МК-161|«Электроники МК-161»]]. Прежде, чем принять данную компактную форму, он прошёл через множество эволюций и представляет собой произведение искусства.
В [[Каллисто|Каллисто 1.0]] адресный интерпретатор способен исполнять [[шитый код]] как из [[Регистры байтовых данных|памяти данных]], так и из [[Память программ|памяти программ]] [[МК-161|«Электроники МК-161»]]. Прежде, чем принять компактную и завершённую форму, он прошёл через множество эволюций и представляет собой произведение искусства — как вышивка или плетение.


В Каллисто-2 адресный интерпретатор существенно упростится, а его работа ускорится, т.к. для работоспособности транслятора достаточно уметь исполнять [[шитый код]] из [[Регистры байтовых данных|памяти данных]].
В Каллисто-2 адресный интерпретатор существенно упростится, а его работа ускорится, т.к. для работоспособности транслятора достаточно уметь исполнять [[шитый код]] из [[Регистры байтовых данных|памяти данных]]. У рассматриваемого адресного интерпретатора сохранится важное преимущество — максимальный объём свободной [[Регистры байтовых данных|памяти данных]] облегчает разработчику создание крупных приложений.


=== NEXT ===
=== NEXT ===
Действие NEXT — основа адресного интерпретатора, передача управления от одного [[токен]]а в цепочке [[шитый код|шитого кода]] к следующему. Каллистянские [[примитив]]ы обычно завершаются командой [[КБП9]], так как адрес NEXT хранится в [[R9]]. Содержимое [[R9]] различно и зависит от того, идёт исполнение [[Шитый код|шитого кода]] из [[Регистры байтовых данных|памяти данных]] или [[Память программ|памяти программ]]. В этих двух случаях адрес NEXT равен NEXTD и NEXTP соответственно.
Действие NEXT — основа адресного интерпретатора, передача управления от одного [[токен]]а в цепочке [[шитый код|шитого кода]] к следующему. Каллистянские [[примитив]]ы обычно завершаются командой [[КБП9]], так как актуальный адрес NEXT хранится в [[R9]]. Содержимое [[R9]] зависит от того, идёт исполнение [[Шитый код|шитого кода]] из [[Регистры байтовых данных|памяти данных]] или [[Память программ|памяти программ]]. В этих двух случаях адрес NEXT равен NEXTD и NEXTP соответственно.
 
[[RE|Регистр E]] содержит число 256. [[Токен]] очередного слова W считывается из [[Шитый код|шитого кода]] в [[R7|регистр 7]]. Регистр выглядит, как вспомогательный, но на самом деле содержимое [[R7]] повторно используется в подпрограммах RPUSHRIP / RPUSHRID. Обращение к ним происходит из CALL с помощью команды [[КППС]], но об этом чуть позже.
 
Считанный [[токен]] W указывает на [[поле кода]] слова, в котором содержится адрес обработчика этого слова. Именно этот трюк (указатель на адрес) делает применённый [[шитый код]] «косвенным». Этот адрес считывается в [[R8]] и команда [[КБП8]] передаёт управление на обработчик. Обработчик всегда написан на [[ЯМК|языке МК]] и содержится в [[Память программ|памяти программ]], но токен W может указывать как на [[Регистры байтовых данных|память данных]], так и на [[Память программ|память программ]].


Действие NEXT не следует путать с каллистянским словом [[NEXT]].
Действие NEXT не следует путать с каллистянским словом [[NEXT]].
Строка 36: Строка 40:
2503 NEXTPP:        RM7 KPRGM RME ∗ RM7 1 + KPRGM + ; Считать MEMW[W], это должно быть CFA очередного слова в шитом коде
2503 NEXTPP:        RM7 KPRGM RME ∗ RM7 1 + KPRGM + ; Считать MEMW[W], это должно быть CFA очередного слова в шитом коде
2504                M8 KGOTO8                      ; передать управление на адрес, записанный в CFA
2504                M8 KGOTO8                      ; передать управление на адрес, записанный в CFA
2505
</pre>
</pre>


=== EXECUTE ===
=== EXECUTE ===
Слово [[EXECUTE]] считывает из [[Стек данных|стека]] [[CFA|токен]], после чего передаёт управление на его обработчик. Эту работу выполняет код, начиная с метки DOEXECRX — он приводится выше в описании NEXT.
Слово [[EXECUTE]] считывает из [[Стек данных|стека]] [[CFA|токен]], после чего передаёт управление на его обработчик. Основную работу выполняет код, начиная с метки DOEXECRX — он приведён выше в описании NEXT.
<pre>
<pre>
2506 JEXEC:                                          ; Обработчик EXECUTE
2506 JEXEC:                                          ; Обработчик EXECUTE
Строка 49: Строка 54:
Действия CALL и RETURN позволяют адресному интерпретатору исполнять не только последовательность [[примитив]]ов, но также использовать в [[шитый код|шитом коде]] слова высокого уровня — обеспечивая вложенность определений «через двоеточие». Этим двум действиям соответствуют каллистянские слова [[Слово :|:]] и [[EXIT]].
Действия CALL и RETURN позволяют адресному интерпретатору исполнять не только последовательность [[примитив]]ов, но также использовать в [[шитый код|шитом коде]] слова высокого уровня — обеспечивая вложенность определений «через двоеточие». Этим двум действиям соответствуют каллистянские слова [[Слово :|:]] и [[EXIT]].


Сохранив в [[Стек возвратов Каллисто|стеке возвратов]] текущую позицию [[Шитый код|шитого кода]] (или считав её оттуда), действия CALL / RETURN передают управление на точки NEXTD / NEXTP (см. выше). Действие CALL в [[Каллисто|Каллисто 1.0]] реализовано дважды, начиная с меток CALLD и CALL. Это обработчики высокоуровневых слов в [[Регистры байтовых данных|памяти данных]] и [[Память программ|памяти программ]] соответственно:
Сохранив в [[Стек возвратов Каллисто|стеке возвратов]] текущую позицию [[Шитый код|шитого кода]] (или считав её оттуда), действия CALL / RETURN передают управление на точки NEXTD / NEXTP (см. выше). Действие CALL в [[Каллисто|Каллисто 1.0]] реализовано дважды, начиная с меток CALLD и CALL. Это обработчики высокоуровневых слов в [[Регистры байтовых данных|памяти данных]] (слова разработчика) и [[Память программ|памяти программ]] (заранее откомпилированные) соответственно:
<pre>
<pre>
2467 CALLD:                                          ;∗∗ CALL, когда управление передаётся в память данных
2467 CALLD:                                          ;∗∗ CALL, когда управление передаётся в память данных

Версия от 21:27, 20 января 2020

Адресный интерпретатор (англ. address interpreter) — интерпретатор косвенного шитого кода.

Если поток исполнения команд уподобить току крови, адресный интерпретатор — сердце Каллисто. Каждая передача управления от одного примитива к другому проходит через адресный интерпретатор. Именно он «гонит кровь» через определения высокого уровня, «оживляя» шитый код и заставляя его работать.

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

К сожалению, сейчас (по состоянию на январь 2018 года) адресный интерпретатор написан на языке МК, что ещё сильней ограничивает быстродействие Каллисто. Оптимизация адресного интерпретатора по быстродействию, как и прошивка его в ПЗУ микроконтроллера является задачей, важной для успеха Каллисто.

История

Впервые косвенный шитый код (англ. indirect-threaded code) появился в Форте 1971-73 годах, когда Чак Мур перенёс транслятор на DEC PDP-11 в National Radio Astronomy Observatory (англ., Шарлотсвилл). С тех пор разные варианты шитого кода применяется в подавляющем числе различных реализаций Форта.

Первый адресный интерпретатор для PDP-11 представлял из себя 2-словный макрос на форт-ассемблере:

    : NEXT   IP )+ W MOV  W )+ ) JMP ;


Реализация

В Каллисто 1.0 адресный интерпретатор способен исполнять шитый код как из памяти данных, так и из памяти программ «Электроники МК-161». Прежде, чем принять компактную и завершённую форму, он прошёл через множество эволюций и представляет собой произведение искусства — как вышивка или плетение.

В Каллисто-2 адресный интерпретатор существенно упростится, а его работа ускорится, т.к. для работоспособности транслятора достаточно уметь исполнять шитый код из памяти данных. У рассматриваемого адресного интерпретатора сохранится важное преимущество — максимальный объём свободной памяти данных облегчает разработчику создание крупных приложений.

NEXT

Действие NEXT — основа адресного интерпретатора, передача управления от одного токена в цепочке шитого кода к следующему. Каллистянские примитивы обычно завершаются командой КБП9, так как актуальный адрес NEXT хранится в R9. Содержимое R9 зависит от того, идёт исполнение шитого кода из памяти данных или памяти программ. В этих двух случаях адрес NEXT равен NEXTD и NEXTP соответственно.

Регистр E содержит число 256. Токен очередного слова W считывается из шитого кода в регистр 7. Регистр выглядит, как вспомогательный, но на самом деле содержимое R7 повторно используется в подпрограммах RPUSHRIP / RPUSHRID. Обращение к ним происходит из CALL с помощью команды КППС, но об этом чуть позже.

Считанный токен W указывает на поле кода слова, в котором содержится адрес обработчика этого слова. Именно этот трюк (указатель на адрес) делает применённый шитый код «косвенным». Этот адрес считывается в R8 и команда КБП8 передаёт управление на обработчик. Обработчик всегда написан на языке МК и содержится в памяти программ, но токен W может указывать как на память данных, так и на память программ.

Действие NEXT не следует путать с каллистянским словом NEXT.

2476 NEXTD:                                          ; NEXT для шитого кода из памяти данных.
2477                 KRM6 RME ∗ KRM6 + M7            ; W := MEMW[RI++] считать шитый код
2478                 1 EE 4 −  FX>=0 NEXTPP          ; Слово из памяти программ?
2479 NEXTDD:         M7 M5 KRM7 RME ∗ KRM5 +         ; Считать MEMW[W], это должно быть CFA очередного слова в шитом коде
2480                 M8 KGOTO8                       ; передать управление на адрес, записанный в CFA
…
2499 NEXTP:                                          ; NEXT для шитого кода из памяти программ.
2500                 PPRM 9044 RME ∗ PPRM 9044 +
2501 DOEXECRX:       M7                              ; W := MEMW[RI++] считать шитый код
2502                 1 EE 4 − FX<0 NEXTDD            ; Слово из области двоичных данных?
2503 NEXTPP:         RM7 KPRGM RME ∗ RM7 1 + KPRGM + ; Считать MEMW[W], это должно быть CFA очередного слова в шитом коде
2504                 M8 KGOTO8                       ; передать управление на адрес, записанный в CFA
2505 

EXECUTE

Слово EXECUTE считывает из стека токен, после чего передаёт управление на его обработчик. Основную работу выполняет код, начиная с метки DOEXECRX — он приведён выше в описании NEXT.

2506 JEXEC:                                          ; Обработчик EXECUTE
2507                 RM3 M8 1 + M3 KRM8              ; POP RX
2508                 PGOTO DOEXECRX                  ; W := RX, JMP MEMW[W]

CALL / RETURN

Действия CALL и RETURN позволяют адресному интерпретатору исполнять не только последовательность примитивов, но также использовать в шитом коде слова высокого уровня — обеспечивая вложенность определений «через двоеточие». Этим двум действиям соответствуют каллистянские слова : и EXIT.

Сохранив в стеке возвратов текущую позицию шитого кода (или считав её оттуда), действия CALL / RETURN передают управление на точки NEXTD / NEXTP (см. выше). Действие CALL в Каллисто 1.0 реализовано дважды, начиная с меток CALLD и CALL. Это обработчики высокоуровневых слов в памяти данных (слова разработчика) и памяти программ (заранее откомпилированные) соответственно:

2467 CALLD:                                          ;∗∗ CALL, когда управление передаётся в память данных
2468                 KGSBC                           ; RPUSH RI ; RX := W, адрес поля кода нового слова
2469                 1 +                             ; RX := PFA−1, передать в указатель шитого кода R6=RI−1
2470 SETRIDAT:
2471                 M6                              ; RI := RX
2472 SETDAT:         .NUMT RPUSHRID
2473                 MC                              ; RC := RPUSHRID        ;∗∗ Следующий вызов −− из памяти данных
2474                 .NUM NEXTD
2475                 M9                              ; R9 := NEXTD           ;∗∗
2476 NEXTD:                                          ; NEXT для шитого кода из памяти данных.
…
2481 ;
2482 RETURN:                                         ; Обработчик EXIT
2483                 RM2 1 − M5 3 + M2
2484                 KRM5 RME ∗ KRM5 +
2485                 PPM 9042                        ; Регистр, увы, мучаем в любом случае
2486                 10001 −
2487                 FX<0 SETRIDAT
2488                 GOTO SETPRG
2489 ;
2490 CALL:                                           ;∗∗ CALL, когда управление передаётся в память программ
2491                 KGSBC                           ; RPUSH RI ; RX := W, адрес поля кода нового слова
2492                 2 +                             ; Теперь RX указывает на его тело
2493 SETRIPRG:
2494                 PPM 9042                        ; R9042 := RX
2495 SETPRG:         .NUMT RPUSHRIP
2496                 MC                              ; RC := RPUSHRIP        ;∗∗ Следующий вызов −− из памяти программ
2497                 .NUM NEXTP
2498                 M9                              ; R9 := NEXTP           ;∗∗
2499 NEXTP:                                          ; NEXT для шитого кода из памяти программ.
…

Реализации CALLD и CALL начинаются с команды КППС, которая заносит в стек возвратов текущую позицию в шитом коде. Эта команда производит обращение к одной из двух подпрограмм, которые ради оптимизации размещены в самом начале Каллисто 1.0. Выбор RPUSHRIP или RPUSHRID зависит от того, требуется сохранить позицию в памяти программ или данных соответственно:

 179 ; Следующие две подпрограммы вызваются косвенно через RC (КППС) из : и DOES>
 180 ; SETRIPRG и SETRIDAT внутри тела ":" содержат ссылки на RPUSHRIP и RPUSHRID
 181 
 182 ; Начало CALL при вызове из памяти программ.
 183 RPUSHRIP:
 184                 PPRM 9042                       ; RX := RI      ; Текущий указатель шитого кода
 185                 ENT RME / FANS <−> KINT M5 ∗ − KM2 RM5 KM2      ; RPUSH (RX)
 186                 RM7 RTN                         ; RX := W, оптимизация
 187 
 188 ;
 189 ; Начало CALL при вызове из памяти данных.
 190 RPUSHRID:
 191                 RM6 10001 +                     ; RX := RI      ; Текущий указатель шитого кода
 192                 ENT RME / FANS <−> KINT M5 ∗ − KM2 RM5 KM2      ; RPUSH (RX)
 193                 RM7 RTN                         ; RX := W, оптимизация

Форт-процессоры

Первая попытка построить форт-компьютер была предпринята John Davies в Англии в 1973 году. Примерно в это время английская обсерватория Джодрелл Бэнк открыла для себя Форт. Подход Davies заключался в переделке компьютера Ferranti (который перестал выпускаться), чтобы оптимизировать его набор инструкций под Форт. Получившийся форт-компьютер был очень быстрый для своего времени.

В 1976 году форт-компьютер выпустила калифорнийская компания Standard Logic (в других источниках General Logic). Dean Sanderson, главный программист Standard Logic (позже он перешёл работать в FORTH Inc.) смог аппаратно реализовать точную инструкцию NEXT, которую адресный интерпретатор Форта использует для перехода от одной высокоуровневой команды к следующей. Их систему широко использовала Почтовая Система США (US Postal System).

В начале 1980'ых фирма Rockwell выпустила микропроцессор Rockwell AIM 65F11 с примитивами Форта в ПЗУ, находящемся на чипе. Эту микросхему успешно использовали во встроенных приложениях.

В 1981 году разработкой форт-процессора занялся Чак Мур — сперва работая в FORTH Inc., а затем создав старт-ап Novix. Основная разработка была завершена в 1984 году, первые прототипы были представлены в начале 1985 года. Разработка Мура была куплена и адаптирована фирмой Harris Semiconductor Corp., став основой их линейки процессоров RTX.

Начав в ранних 1980'ых, группа в Лаборатории прикладной физики штата Мэрилэнд (John Hopkins Applied Physics Laboratory in Maryland) разработала серию экспериментальных форт-профессоров для использования в космосе. Самый успешный из них, названный SC-32 фирмой Silicon Composers в Пало-Альто (Калифорния), использовался для управления ультрафиолетовым телескопом (англ. Hopkins Ultraviolet Telescope), который полетел в шаттле Колумбия в ноябре-декабре 1990 года.

Чак Мур, автор языка Форт, отказался от участия в разработке стандарта ANSI для языка Форт, чтобы посвятить всё своё время разработке «железного» процессора, достойного языка Форт. Эволюция Форта в программно-аппаратную систему привела к возникновению языка colorForth и мультикомпьютерной микросхемы GA144 (англ.).

Защищённый от радиации форт-процессор RTX2010 (англ.) основан на разработках Чака Мура и десятилетиями используется в зарубежных космических аппаратах. В частности, RTX2010 использовался в спускаемом аппарате «Филы» КА «Розетта» (миссия к комете 67P/Чурюмова — Герасименко), работавшего на поверхности кометы с 12 ноября 2014 года по 19 июня 2015 года. Это первая в истории посадка на комету, драматичная и довольно захватывающая, но в целом успешная.

В России разработаны и выпускаются отечественные форт-процессоры, например K1881BE1T и К1894ВГ1Т. Перенос Каллисто на один из этих микропроцессоров позволит достичь максимальной производительности.

Ссылки


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


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