Скачиваний:
97
Добавлен:
03.06.2014
Размер:
5.64 Mб
Скачать

Пример архитектуры команд IJVM

253

Листинг4.2. Программа на языке ассемблерJava

1

ILOAD j

//i=J+k

2ILOAD k

3IADD

4ISTORE l

5

ILOAD l

//if(1—3)

6BIPUSH 3

7IFJCMPEQ LI

8

ILOAD j

//J-J-l

9BIPUSH 1

10ISUB

11ISTORE j

12GOTO L2

13 LI BIPUSH 0

//k-0

14ISTORE k

15L2

Листинг4.3. Программа IJVM в шестнадцатеричном коде

0x15 0x02

0x15 0x03

0x60

0x36 0x01

0x15 0x01

0x10 0x03

0x9F 0x00 OxOD 0x15 0x02

0x10 0x01

0x64

ОхЗб 0x02

 

0xA7

0x00

0x07

0x10

0x00

 

0x36

0x03

 

Скомпилированная программа проста. Сначала j и к помещаются в стек, складываются, а результат сохраняется в i Затем i и константа 3 помещаются в стек и сравниваются Если они равны, то совершается условный переход к L1, где к получает значение 0 Если они не равны, то выполняется часть программы после IF_ICMPEQ После этого осуществляется переход к L2, где сливаются части el se иthen

Стек операндов для программы IJVM, приведенной в листинге 4.2, изображен на рис. 4 12 До начала выполнения программы стек пуст, что показывает горизонтальная черта над цифрой 0 После выполнения первой команды ILOAD j помешается в стек (См на рисунке прямоугольник над цифрой 1 ) Цифра 1 означает, что выполнена команда 1 После выполнения второй команды ILOAD в стеке оказываются уже два слова, как показано в прямоугольнике над цифрой 2 После выполнения команды IADD в стеке остается только одно слово, которое представляет собой сумму j+k. Когда верхнее слово выталкивается из стека и сохраняется в i, стек снова становится пустым

Команда 5 (ILOAD) начинает оператор if. Эта команда помещает i в стек Затем идет константа 3 (в команде 6) После сравнения стек снова становится пустым (7) Команда 8 является началом фрагмента el se Он продолжается вплоть до команды 12, когда совершается переход к метке L2.

254 Глава4.Микроархитектурныйуровень

10

11

12

14

15

Рис. 4.12. Состояние стека после выполнения каждой команды в программе, приведенной в листинге 4.2

Пример реализации микроархитектуры

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

Микрокоманды и их запись

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

Наша система обозначений показывает все действия, которые происходят на одной линии за один цикл. Теоретически для описания этих операций мы могли бы использовать язык высокого уровня. Однако контроль циклов очень важен, поскольку этодает возможность выполнять несколько операций одновременно. Кроме того, такой контроль необходим для того, чтобы можно было проанализировать каждый цикл, понять все операции и проверить их. Если целью разработки является повышение скорости и производительности, то имеет значение каждый цикл. При практической реализации в программу включается множество различных приемов для экономии циклов. В такой экономии есть большая выгода: четырехцикловая команда, которую можно сократить на два цикла, будет после этого выполняться в два раза быстрее. И такое повышение скорости достигается каждый раз, когда мы выполняем эту команду.

Один из возможных подходов — просто выдать список сигналов, которые должны активизироваться в каждом цикле. Предположим, что в одном цикле мы хотим

Пример реализации микроархитектуры

255

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

ReadRegister=SP, ALIMNC, WSP, Read, NEXT_ADDRESS=122

Здесь WSP значит «записать регистр SP». Эта запись полная, но она сложна для понимания. Вместо этого мы соединим эти операции и передадим в записи результат действий:

SP-SP+1, rd

Назовем наш микроассемблер высокого уровня «MAL» (Micro Assembly Language — микроассемблер). По-французски «MAL» значит «болезнь» — это то, что с вами случится, если вы будете писать слишком большие программы на этом языке. Язык MAL разработан для того, чтобы продемонстрировать основные характеристики микроархитектуры. Во время каждого цикла могут записываться любые регистры, но обычно записывается только один. Значение только одного регистра может передаваться на шину В и в АЛУ. На шине А может быть +1, 0, -1 и регистр Н. Следовательно, для обозначения определенной операции мы можем использовать простой оператор присваивания, как в языке Java. Например, чтобы копировать регистр SP в регистр MDR, мы можем написать:

MDR=SP

Чтобы показать, что мы используем какую-либо функцию АЛУ, мы можем написать,например:

MDR-H+SP

Эта строка означает, что значение регистра Н складывается со значением регистра SP и результат записывается в регистр MDR. Операция сложения коммутативна (этозначит,что порядокоперандов неимеетзначения), поэтомуданное выше выражение можно записать в виде:

MDR=SP+H

и при этом породить ту же 36-битную микрокоманду, хотя, строго говоря, Н является левым операндом АЛУ.

Мы должны использовать только допустимые операции. Самые важные операции приведены в табл. 4.3, где SOURCE — значение любого из регистров MDR, PC, MBR, MBRU, SP, LV, CPP, TOS и ОРС (MBRU (MBR Unsigned) - это значение регистра MBR без знака). Все эти регистры могут выступать в качестве источников значений для АЛУ (они поступают в АЛУ через шину В). Сходным образом DEST может обозначать любой из следующих регистров: MAR, MDR, PC, SP, LV, CPP, TOS, ОРС и Н. Любой из этих регистров может быть пунктом назначения для выходного сигнала АЛУ, который передается к регистрам по шине С. Многие, казалось бы, разумные утверждения недопустимы. Например, выражение

MDR=SP+MDR

выглядит вполне корректно, но эту операцию нельзя выполнить в тракте данных, изображенном на рис. 4.5, за один цикл. Такое ограничение существует, поскольку для операции сложения (в отличие от увеличения или уменьшения на 1) один из операндов должен быть значением регистра Н. Точно так же, выражение

H=H-MDR

2 5 6 Глава 4. Микроархитектурный уровень

могло бы пригодиться, но оно невозможно, поскольку единственным возможным источником вычитаемого является регистр Н. Ассемблер должен отбрасывать выражения, которые кажутся пригодными, но в действительности недопустимы.

В нашей системе записи допускается использование нескольких операторов присваивания. Например, чтобы прибавить 1 к регистру SP и сохранить полученное значение в регистрах SP и MDR, нужно записать следующее:

SP=MDR=SP+1

Для обозначения процессов считывания из памяти и записи в память слов по 4 байта мы будем вставлять в микрокоманду слова rd и wr. Для вызова байта через 1-байтный порт используется команда fetch. Операции присваивания и операции взаимодействия с памятью могут происходить в одном и том же цикле. То, что происходит в одном цикле, записывается в одну строку.

Чтобы избежать путаницы, напомним еще раз, что Mic-1 может обращаться к памяти двумя способами. При чтении и записи 4-байтных слов данных используются регистры МAR/MDR. Эти процессы показываются в микрокомандах словами rd и wr соответственно. При чтении 1-байтных кодов операций из потока команд используются регистры PC/MBR. В микрокоманде это показывается словом fetch. Оба типа операций взаимодействия с памятью могут происходить одновременно.

Однако один и тот же регистр не может получать значение из памяти и тракта данных в одном и том же цикле. Рассмотрим кусок программы

MAR=SP. rd MDR-H

В результате выполнения первой микрокоманды значение из памяти приписывается регистру MDR в конце второй микрокоманды. Однако вторая микрокоманда в то же самое время приписывает другое значение регистру MDR. Эти две операции присваивания конфликтуют, поскольку результаты не определены.

Таблица4.3.Вседопустимыеоперации.Любуюизперечисленныхоперацийможно расширить, добавив «<<8», что означает сдвиг результата влево на 1 байт. Например, часто используется операция H=MBR«8

DEST=H

DEST=SOURCE

DEST=H

DEST=SOURCE

DEST=H+SOURCE

DEST=H+SOURCE+1

DEST=H+1

DEST=SOURCE+1

DEST=SOURCE-H

DEST=SOURCE-1 DEST= -H

DEST=H И SOURCE DEST=H ИЛИ SOURCE DEST=O

DESTM

DEST=-1

Пример реализации микроархитектуры

257

Помните, что в каждой микрокоманде должен явно показываться адрес следующей микрокоманды Однако часто бывает так, что микрокоманда вызывается толькооднойдругой микрокомандой, а именно той микрокомандой, которая находится в строке над ней. Чтобы упростить работу программиста, микроассемблер обычно приписывает адрес каждой микрокоманде (порядок адресов может и не соответствовать последовательности микрокоманд в управляющей памяти) и заполняетполе NEXT_ADDRESS, так чтопоследовательность выполнения микрокоманд соответствует последовательности строк микропрограммы.

Однако программисту иногда нужно совершить переход, условный или безусловный. Запись безусловных переходов проста:

goto label

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

goto Mainl

Отметим, что в тракте данных происходят обычные операции даже во время выполнения микрокоманд, которые содержат goto. В любой микрокоманде есть поле NEXT_ADDRESS. Команда goto сообщает ассемблеру, что в это поле вместо адреса микрокоманды, записанной в следующей строке, нужно поместить особое значение. В принципе каждая строка должна содержать запись goto, но если нужный адрес — это адрес микрокоманды, записанной в следующей строке, goto может опускаться для удобства.

Для условных переходов нам требуется другая запись Помните, что JAMN и JAMZ используют биты N и Z соответственно. Например, иногда нужно проверить, не равно ли значение регистра 0. Для этого можно было бы пропустить это значение через АЛУ, сохранив его после этого в том же регистре. Тогда мы бы написали:

T0S=TOS

Запись выглядит забавно, но выполняет необходимые действия (устанавливает триггер Z и записывает значение в регистре TOS). В целях удобочитаемости микропрограммы мы расширили язык MAL, добавив два новых воображаемых регистра N и Z, которым можно присваивать значения. Например, строка

Z=TOS

пропускает значение регистра TOS через АЛУ, устанавливая триггер Z (и N), но при этом не сохраняет значение ни в одном из регистров. Использование регистра Z или N в качестве пункта назначения показывает микроассемблеру, что нужно установить все биты в поле С (см. рис. 4.4) на 0. Тракт данных проходит обычный цикл, выполняются все обычные допустимые операции, но ни один из регистров не записывается. Не важно, где находится пункт назначения' в регистре N или в регистре Z. Микрокоманды, которые при этом порождает микроассемблер, одинаковы. Программисты, выбравшие не тот регистр, в наказание будут неделю работать на первом компьютере IBM PC с частотой 4,77 МГц.

258 Глава 4. Микроархитектурный уровень

Чтобы микроассемблер установил бит JAMZ, нужно написать следующее: if(Z) goto LI, else goto L2

Поскольку аппаратное обеспечение требует, чтобы 8 младших битов этих адресов совпадали, задача микроассемблера состоит в том, чтобы присвоить им такие адреса. С другой стороны, L2 может находиться в любом из младших 256 слов управляющей памяти, поэтому микроассемблер без труда найдет подходящую пару.

Часто эти два утверждения сочетаются. Например,

Z=TOS. if(Z) goto LI. else goto L2

В результате такой записи MAL породит микрокоманду, в которой значение регистра TOS пропускается через АЛУ, но при этом нигде не сохраняется, так что это значение устанавливает бит Z. Сразу после загрузки из АЛУ бит Z соединяется со старшим битом регистра МРС через схему ИЛИ, вследствие чего адрес следующей микрокоманды будет вызван или из L2, или из Ы. Значение регистра МРС стабилизируется, и он сможет использоватьегодля вызоваследующей микрокоманды.

Наконец, нам нужна специальная запись, чтобы использовать бит JMPC:

goto (MBR OR value)

Эта запись сообщает микроассемблеру, что нужно использовать value (значение) для поля NEXT^ADDRESS и установить битJMPC, так чтобы MBR соединялся через схему ИЛИ с регистром МРС вместе со значением NEXT_ADDRESS. Если value равно 0, достаточно написать:

goto (MBR)

Отметим, что только 8 младших битов регистра MBR соединяются с регистром МРС (см. рис. 4.5), поэтому вопрос о знаковом расширении тут не возникает. Также отметим, что используется то значение MBR, которое доступно в конце текущего цикла.

Реализация IJVM с использованием Mic-1

Сейчас мы уже дошли до того момента, когда можно соединить все части вместе. В табл. 4.4-приводится микропрограмма, которая работает на микроархитектуре Mic-1 и интерпретирует IJVM. Программа очень короткая — всего 112 микрокоманд. Таблица состоит из трех столбцов. В первом столбце записано символическое обозначение микрокоманды, во втором — сама микрокоманда, а в третьем — комментарий. Как мы уже говорили, последовательность микрокоманд не обязательно соответствует последовательности адресов в управляющей памяти.

Выбор названий большинства регистров, изображенных нарис. 4.1, должен стать очевидным. Регистры СРР (Constant Pool Pointer — указатель набора констант), LV (Local Variable pointer — указатель фрейма локальных переменных) и SP (Stack Pointer — указатель стека) содержат указатели адресов набора констант, фрейма локальных переменных и верхнего элемента в стеке соответственно, а регистр PC (Program Counter — счетчик команд) содержит адрес байта, который нужно вызвать следующим из потока команд. Регистр MBR (Memory Buffer Register — буферный регистр памяти) — это 1-байтовый регистр, который содержит байты потока команд, поступающих из памяти для интерпретации. TOS и ОРС — дополнительные регистры. Они будут описаны ниже.

Пример реализации микроархитектуры

259

В определенные моменты в каждом из этих регистров обязательно находится определенное значение. Однако каждый из них также может использоваться в качестве временного регистра в случае необходимости. В начале и конце каждой команды регистр TOS (Top Of Stack register — регистр вершины стека) содержит значение адреса памяти, на который указывает SP. Это значение избыточно, поскольку его всегда можно считать из памяти, но если хранить это значение в регистре, то обращение к памяти не требуется. Для некоторых команд использование регистра TOS, напротив, влечет за собой больше обращений к памяти. Например, команда POP отбрасывает верхнее слово стека и, следовательно, должна вызвать новое значение вершины стека из памяти и записать его в регистр TOS.

ОРС — временный регистр. У него нет определенного заданного назначения. В нем, например, может храниться адрес кода операции для команды перехода, пока значение PC увеличивается, чтобы получить доступ к параметрам. Он также используется в качестве временного регистра в командах условного перехода.

Как и все интерпретаторы, микропрограмма, приведенная в табл. АЛ, включает в себя основной цикл, который вызывает, декодирует и выполняет команды интерпретируемой программы (в данном случае команды IJVM). Основной цикл начинается со строки Mainl, а именно с инварианта (утверждения), что в регистр PC уже загружен адрес ячейки памяти, в которой содержится код операции. Более того, этот код операции уже вызван из памяти в регистр MBR. Когда мы вернемся к этой ячейке, мы должны быть уверены, что значение PC уже обновлено и указывает на код следующей операции, а сам код операции уже вызван из памяти в MBR.

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

А теперь мы можем объяснить главную причину, почему в каждой микрокоманде явным образом указывается следующая микрокоманда и почему последовательность команд может и не соответствовать порядку их расположения в памяти. Все адреса управляющей памяти, соответствующие кодам операций, должны быть зарезервированы для первого слова интерпретатора соответствующей команды. Так, из табл. 4.2 мы видим, что программа, которая интерпретирует команду POP, начинается в ячейке 0x57, а программа, которая интерпретирует команду DUP, начинается в ячейке 0x59. (Как язык MAL узнает, что команду POP нужно поместить в ячейку 0x57, — одна из загадок Вселенной. Предположительно, где-то существует файл, который сообщает ему об этом.)

К сожалению, программа, интерпретирующая команду POP, включает в себя три микрокоманды, поэтому если их расположить в памяти последовательно, то эта программа смешается с началом команды DUP. Поскольку все адреса управляющей памяти, которые соответствуют кодам операций, зарезервированы, то все микрокоманды, идущие после первой микрокоманды в каждой последовательности, должны размещаться в промежутках между зарезервированными адресами. По этой

260 Глава 4. Микроархитектурный уровень

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

Чтобы понять, как работает интерпретатор, предположим, что регистр MBR содержит значение 0x60, то есть код операции IADO (см. табл. 4.2). В основном цикле, который состоит из одной микрокоманды, выполняется следующее:

1. Значение регистра PC увеличивается, и теперь он содержит адрес первого байта после кода операции.

2.Начинается передача следующего байта в регистр MBR. Этот байт понадобится рано или поздно либо в качестве операнда текущей команды IJVM, либо в качестве кода следующей операции (как в случае с командой IADD, у которой нет операндов).

3.Совершается переход к адресу, который содержался в регистре MBR в начале цикла Main 1. Номер адреса равен значению кода операции, которая выполняется в данный момент. Этот адрес был помещен туда предыдущей микрокомандой. Отметим, что значение, которое вызывается из памяти во время этой микрокоманды, не играет никакой роли в межуровневом переходе.

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

Таблица 4.4. Микропрограмма для Mic-1

Микрокоманда

Операции

Комментарий

Maini

PC=PC+1; fetch; goto(MBR)

MBR содержит код операции; получение

 

 

следующего байта; отсылка

пор!

goto Maini

Ничего не происходит

iaddi

 

MAR=SP=SP-1;rd

Чтениеслова,идущегопослеверхнегословастека

iadd2

H=TOS

Н = вершина стека

 

 

iadd3

MDR=TOS=MDR+H;wr;

Суммированиедвухверхнихслов;запись

 

goto Main 1

суммывверхнююпозициюстека

isubi

MAR=SP=SP-1.rd

Чтение слова, идущего после верхнего слова стека

isub2

H=TOS

Н = вершина стека

isub3

MDR=TOS=MDR-H;wr;

Вычитание;записьрезультатаввершинустека

 

goto Maini

 

iandi

MAR=SP=SP-1;rd

Чтениеслова,идущегопослеверхнегословастека

iand2

H=TOS

Н = вершина стека

iand3

MDR=TOS=MDRHH,wr;

ОперацияИ;записьрезультатаввершинустека

 

goto Maini

 

ior1

MAR=SP=SP-1;rd

Чтениеслова,идущегопослеверхнегослова

стека

 

 

ior2

H=TOS

Н = вершина стека

ior3

М0Р=ТО5=МОРИЛИН;

Операция ИЛИ; запись результата в вершину стека

 

wr;gotoMaini

 

duol

MAR=SP=SP+1

УвеличениеSPна 1 и копирование результата

 

 

в регистр MAR

Пример реализации микроархитектуры

261

Микрокоманда Операции

Комментарий

dup2

рор1

рор2

рорЗ swapi

swap2

swap3

swap4

swap5

swap6 bipushi bipush2

bipush3

iloadi

iload2

iload3

iload4

iload5

istore1

istore2

istore3

istore4

istore5

istore6 widei

widejloadi

wide_iload2 wide_iload3 wide_iload4

MDR=TOS; wr; goto Maini MAR=SP=SP-1;rd

TOS^MDR; goto Maini MAR=SP=SP-1;rd

MAR=SP

H=MDR; wr

Запись нового слова в стек Чтение слова, идущего после верхнего слова стека

Программа ждет, пока считается из памяти новое значение регистра TOS

Копирование нового слова в регистр TOS

Установка регистра MAR на значение SP-1; чтение второго слова из стека

Установка регистра MAR на верхнее слово стека

Сохранение значения TOS в регистре Н; запись второго слова в вершину стека

MDR=TOS

Копирование прежнего значения TOS в регистр MDR

MAR=SP-1;wr

Установка регистра MAR на значение SP-1;

 

запись второго слова в стек

TOS-H; goto Maini

Обновление TOS

SP=MAR=SP+1

MBR = байт, который нужно поместить в стек

PC=PC+1; fetch

Увеличение PC на 1; вызов кода следующей

 

операции

MDR=TOS=MBR;wr;

Добавление к байту дополнительного знакового

goto Maini

разряда и запись значения в стек

H=LV

MBR содержит индекс; копирование значения

 

L V B H

MAR=MBRU+H;rd

MAR = адрес локальной переменной, которую

 

нужно поместить в стек

MAR=SP=SP+1

Регистр SP указывает на новую вершину стека;

 

подготовка к записи

PC=PC+1; fetch; wr

Увеличение значения PC на 1, вызов кода

 

следующей операции, запись вершины стека

TOS=MDR;gotoMam1

Обновление TOS

H=LV

MBR содержит индекс; копирование значения

 

L V B H

MAR=MBRU+H

MAR = адрес локальной переменной, в которую

 

нужно сохранить слово из стека

MDR=TOS; wr

Копирование значения TOS в регистр MDR;

 

запись слова

SP=MAR=SP-1;rd PC=PC+1; fetch

TOS=MDR; goto Main 1 PC=PC+1;fetch, goto(MBR ИЛИ 0x100) PC=PC+1;fetch

H=MBRU«8

н=мвриилин

MAR=LV+H;rd; goto iload3

Чтение из стека второго слова сверху

Увеличение PC на 1; вызов следующего кода операции

Обновление TOS

Межуровневый переход к старшим адресам

MBR содержит первый байт индекса; вызов второго байта

Н= первый байт индекса, сдвинутый влево на 8 битов

Н= 16-битный индекс локальной переменной

MAR = адрес локальной переменной, которую нужно записать в стек

продолжение^

262 Глава 4. Микроархитектурный уровень

Таблица 4.4 (продолжение)

Микрокоманда Операции

widejstorei PC=PC+1;fetch

Комментарий

MBR содержит первый байт индекса; вызов второго байта

wide_istore2

H=MBRU«8

Н = первый байт индекса, сдвинутый влево

 

 

на 8 битов

wide_istore3

H=MBRU ИЛИ Н

Н = 16-битный индекс локальной переменной

wide_istore4

MAR=LV+H; rd; goto istore3

MAR = адрес локальной переменной, в которую

 

 

нужно записать слово из стека

Idc_w1

PC=PC+1;fetch

MBR содержит первый байт индекса; вызов

 

 

второго байта

Idc_w2 H=MBRU«8

Idc_w3

н^мвииилин

Idc_w4

MAR=H+CPP; rd;

 

goto iload3

iincl

H=LV

iinc2

MAR=MBRU+H;rd

iinc3

PC=PC+1; fetch

iinc4

H=MDR

iinc5

PC=PC+1; fetch

iinc6

MDR=MBR+H;wr,

 

goto Maini

gotoi

OPC=PC-1

goto2

PC=PC+1; fetch

goto3

H=MBR«8

goto4

H=MBRU ИЛИ Н

goto5

PC=OPC+H; fetch

goto6

goto Maini

ifIt1

MAR=SP=SP-1;rd

iflt2

OPC=TOS

iflt3

TOS=MDR

mt4

N=OPC; if(N) goto T;

 

else goto F

ifeqi

MAR=SP=SP~1;rd

ifeq2

OPC=TOS

ifeq3

TOS=MDR

ifeq4

ZOPC;if(Z)gotoT;

 

else goto F

ifjcmpeqi

MAR=SP=SP-1;rd

if_icmpeq2

MAR=SP=SP-1

Н= первый байт индекса, сдвинутый влево на 8 битов

Н= 16-битный индекс константы в наборе констант MAR = адрес константы в наборе констант

MBR содержит индекс; копирование значения

L V B H

Копирование суммы значения LV и индекса в регистр MAR; чтение переменной

Вызов константы Копирование переменной в регистр Н

Вызов следующего кода операции

Запись суммы в регистр MDR; обновление переменной

Сохранение адреса кода операции

MBR = первый байт смещения; вызов второго байта

Сдвиг первого байта влево на 8 битов и сохранение его в регистре Н

Н =16-битное смещение перехода Суммирование смещения и ОРС Ожидание вызова следующего кода операции Чтение второго сверху слова в стеке Временное сохранение TOS в ОРС

Запись новой вершины стека в TOS Переход в бит N

Чтение второго сверху слова е стеке Временное сохранение TOS в ОРС Запись новой вершины стека в TOS Переход в бит Z

Чтение второго сверху слова в стеке

Установка регистра MAR на чтение новой вершины стека

if icmpeq3

H=MDR; rd

Копирование второго слова из стека в регистр Н