Адресный интерпретатор: различия между версиями
AtH (обсуждение | вклад) |
Нет описания правки |
||
(не показаны 52 промежуточные версии 1 участника) | |||
Строка 1: | Строка 1: | ||
'''Адресный интерпретатор''' (''англ.'' address interpreter) — интерпретатор [[Шитый код|косвенного шитого кода]]. | '''Адресный интерпретатор''' (''англ.'' address interpreter) — интерпретатор [[Шитый код|косвенного шитого кода]]. | ||
'' | Если поток исполнения команд уподобить току крови, то ''адресный интерпретатор'' — сердце [[Каллисто]]. Каждая передача управления от одного [[примитив]]а к другому проходит через ''адресный интерпретатор''. Именно он «гонит кровь» через [[Слово :|определения высокого уровня]], «оживляя» [[шитый код]] и заставляя его [[EXECUTE|работать]]. | ||
''Адресный интерпретатор'' [[Каллисто|Каллисто 1.0]] использует [[единое адресное пространство]], что позволяет исполнять [[шитый код]] как из [[Регистры байтовых данных|байтовой памяти]], так и из [[Память программ|памяти программ]]. Такой подход делает его в несколько раз сложней и медленней, чем принято в Форте. В Каллисто-2 планируется упростить адресный интерпретатор, запретив [[шитый код]] в [[Память программ|памяти программ]]. | |||
К сожалению, сейчас (по состоянию на | К сожалению, сейчас (по состоянию на январь 2018 года) ''адресный интерпретатор'' написан на [[ЯМК|языке МК]], что ещё сильней ограничивает быстродействие [[Каллисто]]. Оптимизация ''адресного интерпретатора'' по быстродействию, как и прошивка его в ПЗУ [[микроконтроллер]]а является задачей, важной для успеха [[Каллисто]]. | ||
== История == | == История == | ||
Строка 15: | Строка 15: | ||
== Реализация == | == Реализация == | ||
В [[Каллисто|Каллисто 1.0]] адресный интерпретатор способен исполнять [[шитый код]] как из [[Регистры | В [[Каллисто|Каллисто 1.0]] адресный интерпретатор способен исполнять [[шитый код]] как из [[Регистры байтовых данных|памяти данных]], так и из [[Память программ|памяти программ]] [[МК-161|«Электроники МК-161»]]. Прежде, чем принять компактную и завершённую форму, он прошёл через множество эволюций и представляет собой произведение искусства — как вышивка или плетение. | ||
В Каллисто-2 адресный интерпретатор существенно упростится, а его работа ускорится, т.к. для работоспособности транслятора достаточно уметь исполнять [[шитый код]] из [[Регистры байтовых данных|памяти данных]]. У рассматриваемого адресного интерпретатора сохранится важное преимущество — максимальный объём свободной [[Регистры байтовых данных|памяти данных]] облегчает разработчику создание крупных приложений. | |||
=== NEXT === | === NEXT === | ||
Действие NEXT — | Действие NEXT — основа адресного интерпретатора, передача управления от одного [[токен]]а в цепочке [[шитый код|шитого кода]] к следующему. Каллистянские [[примитив]]ы обычно завершаются командой [[КБП9]], так как актуальный адрес NEXT хранится в [[R9]]. Содержимое [[R9]] зависит от того, идёт исполнение [[Шитый код|шитого кода]] из [[Регистры байтовых данных|памяти данных]] или [[Память программ|памяти программ]]. В этих двух случаях адрес NEXT равен NEXTD и NEXTP соответственно. | ||
[[RE|Регистр E]] содержит число 256. [[Токен]] очередного слова W считывается из [[Шитый код|шитого кода]] в [[R7|регистр 7]]. Регистр выглядит, как вспомогательный, но на самом деле содержимое [[R7]] повторно используется в подпрограммах RPUSHRIP / RPUSHRID. Обращение к ним происходит из CALL с помощью команды [[КППС]], но об этом чуть позже. | |||
Считанный [[токен]] W указывает на [[поле кода]] слова, в котором содержится адрес обработчика этого слова. Именно этот трюк (указатель на адрес) делает применённый [[шитый код]] «косвенным». Этот адрес считывается в [[R8]] и команда [[КБП8]] передаёт управление на обработчик. Обработчик всегда написан на [[ЯМК|языке МК]] и содержится в [[Память программ|памяти программ]], но токен W может указывать как на [[Регистры байтовых данных|память данных]], так и на [[Память программ|память программ]]. | |||
Действие NEXT не следует путать с каллистянским словом [[NEXT]]. | |||
<pre> | <pre> | ||
2476 NEXTD: ; NEXT для шитого кода из памяти данных. | 2476 NEXTD: ; NEXT для шитого кода из памяти данных. | ||
Строка 32: | Строка 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|токен]], после чего передаёт управление на его обработчик. | Слово [[EXECUTE]] считывает из [[Стек данных|стека]] [[CFA|токен]], после чего передаёт управление на его обработчик. Основную работу выполняет код, начиная с метки DOEXECRX — он приведён выше в описании NEXT. | ||
<pre> | <pre> | ||
2506 JEXEC: ; Обработчик EXECUTE | 2506 JEXEC: ; Обработчик EXECUTE | ||
Строка 43: | Строка 52: | ||
=== CALL / RETURN === | === CALL / RETURN === | ||
Действия CALL и RETURN позволяют адресному интерпретатору исполнять не только последовательность [[примитив]]ов, но также использовать в [[шитый код|шитом коде]] слова высокого уровня — обеспечивая вложенность определений «через двоеточие». Этим двум действиям соответствуют каллистянские слова [[Слово :|:]] и [[EXIT]]. | |||
Сохранив в [[Стек возвратов Каллисто|стеке возвратов]] текущую позицию [[Шитый код|шитого кода]] (или считав её оттуда), действия CALL / RETURN передают управление на точки NEXTD / NEXTP (см. выше). Действие CALL в [[Каллисто|Каллисто 1.0]] реализовано дважды, начиная с меток CALLD и CALL. Это обработчики высокоуровневых слов в [[Регистры байтовых данных|памяти данных]] (слова разработчика) и [[Память программ|памяти программ]] (заранее откомпилированные) соответственно: | |||
<pre> | <pre> | ||
2467 CALLD: ;∗∗ CALL, когда управление передаётся в память данных | 2467 CALLD: ;∗∗ CALL, когда управление передаётся в память данных | ||
Строка 76: | Строка 87: | ||
2499 NEXTP: ; NEXT для шитого кода из памяти программ. | 2499 NEXTP: ; NEXT для шитого кода из памяти программ. | ||
… | … | ||
</pre> | |||
Реализации CALLD и CALL начинаются с команды [[КППС]], которая заносит в [[Стек возвратов Каллисто|стек возвратов]] текущую позицию в [[Шитый код|шитом коде]]. Эта команда производит обращение к одной из двух подпрограмм, которые ради оптимизации размещены в самом начале [[Каллисто|Каллисто 1.0]]. Выбор RPUSHRIP или RPUSHRID зависит от того, требуется сохранить позицию в [[Память программ|памяти программ]] или [[Регистры байтовых данных|данных]] соответственно: | |||
<pre> | |||
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, оптимизация | |||
</pre> | </pre> | ||
Текущая версия от 18:34, 12 марта 2022
Адресный интерпретатор (англ. 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Т. Перенос Каллисто на один из этих микропроцессоров позволит достичь максимальной производительности.
Ссылки[править]
- Адресный интерпретатор Каллисто Классик находится в теле слова :, см. метки NEXTP и NEXTD
- Форт в железе! Форт-процессор Дофин-1620 (кодировка Windows)
- Форт-процессор EQUINOX и его обсуждение на форуме
- Randy Dumse, "The R65F11 FORTH Chip," "FORTH Dimensions", Vol.5, No.2, p.25.
У этой статьи нет иллюстраций. Вы можете помочь проекту, добавив их. |
Это заготовка статьи. Вы можете помочь проекту, дополнив её. |