Редактирование:
Адресный интерпретатор
(раздел)
Перейти к навигации
Перейти к поиску
Внимание:
Вы не вошли в систему. Ваш IP-адрес будет общедоступен, если вы запишете какие-либо изменения. Если вы
войдёте
или
создадите учётную запись
, её имя будет использоваться вместо IP-адреса, наряду с другими преимуществами.
Анти-спам проверка.
Не
заполняйте это!
== Реализация == В [[Каллисто|Каллисто 1.0]] адресный интерпретатор способен исполнять [[шитый код]] как из [[Регистры байтовых данных|памяти данных]], так и из [[Память программ|памяти программ]] [[МК-161|«Электроники МК-161»]]. Прежде, чем принять компактную и завершённую форму, он прошёл через множество эволюций и представляет собой произведение искусства — как вышивка или плетение. В Каллисто-2 адресный интерпретатор существенно упростится, а его работа ускорится, т.к. для работоспособности транслятора достаточно уметь исполнять [[шитый код]] из [[Регистры байтовых данных|памяти данных]]. У рассматриваемого адресного интерпретатора сохранится важное преимущество — максимальный объём свободной [[Регистры байтовых данных|памяти данных]] облегчает разработчику создание крупных приложений. === 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> 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 </pre> === EXECUTE === Слово [[EXECUTE]] считывает из [[Стек данных|стека]] [[CFA|токен]], после чего передаёт управление на его обработчик. Основную работу выполняет код, начиная с метки DOEXECRX — он приведён выше в описании NEXT. <pre> 2506 JEXEC: ; Обработчик EXECUTE 2507 RM3 M8 1 + M3 KRM8 ; POP RX 2508 PGOTO DOEXECRX ; W := RX, JMP MEMW[W] </pre> === CALL / RETURN === Действия CALL и RETURN позволяют адресному интерпретатору исполнять не только последовательность [[примитив]]ов, но также использовать в [[шитый код|шитом коде]] слова высокого уровня — обеспечивая вложенность определений «через двоеточие». Этим двум действиям соответствуют каллистянские слова [[Слово :|:]] и [[EXIT]]. Сохранив в [[Стек возвратов Каллисто|стеке возвратов]] текущую позицию [[Шитый код|шитого кода]] (или считав её оттуда), действия CALL / RETURN передают управление на точки NEXTD / NEXTP (см. выше). Действие CALL в [[Каллисто|Каллисто 1.0]] реализовано дважды, начиная с меток CALLD и CALL. Это обработчики высокоуровневых слов в [[Регистры байтовых данных|памяти данных]] (слова разработчика) и [[Память программ|памяти программ]] (заранее откомпилированные) соответственно: <pre> 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 для шитого кода из памяти программ. … </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>
Описание изменений:
Пожалуйста, учтите, что любой ваш вклад в проект «ПМК вики» может быть отредактирован или удалён другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см.
Pmkwiki:Авторские права
).
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!
В целях защиты вики от автоматического спама в правках просим вас решить следующую каптчу:
Отменить
Справка по редактированию
(в новом окне)
Навигация
Персональные инструменты
Вы не представились системе
Обсуждение
Вклад
Создать учётную запись
Войти
Пространства имён
Статья
Обсуждение
русский
Просмотры
Читать
Править
История
Ещё
Поиск
Навигация
Заглавная страница
Свежие правки
Случайная страница
Справка по MediaWiki
Инструменты
Ссылки сюда
Связанные правки
Служебные страницы
Сведения о странице