Компьютер с одним набором инструкций ( OISC ), иногда называемый компьютером с окончательным сокращенным набором инструкций ( URISC ), представляет собой абстрактную машину , которая использует только одну инструкцию, что устраняет необходимость в коде операции машинного языка . [1] [2] [3] При разумном выборе одной инструкции и предоставлении произвольного количества ресурсов OISC способен стать универсальным компьютером таким же образом, как и традиционные компьютеры с несколькими инструкциями. [2] : 55 OISC были рекомендованы в качестве вспомогательных средств для обучения архитектуре компьютеров [1] : 327 [2] : 2 и использовались в качестве вычислительных моделей в исследованиях структурных вычислений. [3] Первый компьютер на углеродных нанотрубках представляет собой 1-битный компьютер с одним набором инструкций (и имеет всего 178 транзисторов). [4]
В полной по Тьюрингу модели каждая ячейка памяти может хранить произвольное целое число, и – в зависимости от модели [ необходимо разъяснение ] – может быть произвольное количество ячеек. Сами инструкции находятся в памяти как последовательность таких целых чисел.
Существует класс универсальных компьютеров с одной инструкцией, основанной на манипуляции битами, такой как копирование битов или инверсия битов . Поскольку их модель памяти конечна, как и структура памяти, используемая в реальных компьютерах, эти машины для манипуляции битами эквивалентны реальным компьютерам, а не машинам Тьюринга. [5]
Известные в настоящее время OISC можно условно разделить на три основные категории:
Машины для манипулирования битами представляют собой простейший класс.
Машина FlipJump имеет 1 инструкцию, a;b - переворачивает бит a, затем переходит к b. Это самый примитивный OISC, но он все еще полезен. Он может успешно выполнять математические/логические вычисления, ветвление, указатели и вызывать функции с помощью своей стандартной библиотеки.
Машина для копирования битов [5] , называемая BitBitJump, копирует один бит в памяти и безусловно передает выполнение по адресу, указанному одним из операндов инструкции. Этот процесс оказывается способным к универсальному вычислению (т. е. способным выполнять любой алгоритм и интерпретировать любую другую универсальную машину), поскольку копирование битов может условно изменять адрес копирования, который будет впоследствии выполнен.
Другая машина, называемая Toga Computer, инвертирует бит и передает выполнение условно в зависимости от результата инверсии. Уникальная инструкция — TOGA(a,b), что означает TOG gle a A и переход к b, если результат операции переключения истинен.
Подобно BitBitJump, многобитовая копировальная машина копирует несколько бит одновременно. Проблема вычислительной универсальности в этом случае решается путем хранения предопределенных таблиц переходов в памяти. [ необходимо разъяснение ]
Архитектура с транспортным запуском (TTA) — это конструкция, в которой вычисления являются побочным эффектом переноса данных. Обычно некоторые регистры памяти (порты запуска) в общем адресном пространстве выполняют назначенную операцию, когда инструкция ссылается на них. Например, в OISC, использующем одну инструкцию копирования из памяти в память, это делается путем запуска портов, которые выполняют арифметические и указатели инструкций переходов при записи.
Арифметические машины Turing-complete используют арифметическую операцию и условный переход. Как и два предыдущих универсальных компьютера, этот класс также Turing-complete. Инструкция работает с целыми числами, которые также могут быть адресами в памяти.
В настоящее время известно несколько OISC этого класса, основанных на различных арифметических операциях:
Распространенные варианты выбора для одиночной инструкции:
Только одна из этих инструкций используется в данной реализации. Следовательно, нет необходимости в опкоде для определения того, какую инструкцию выполнять; выбор инструкции заложен в конструкции машины, и OISC обычно называется в честь инструкции, которую она использует (например, SBN OISC, [2] : 41 язык SUBLEQ, [3] : 4 и т. д.). Каждая из приведенных выше инструкций может быть использована для построения полной по Тьюрингу OISC.
В этой статье представлены только инструкции на основе вычитания из тех, которые не вызываются транспортом. Однако можно построить полные машины Тьюринга, используя инструкцию, основанную на других арифметических операциях, например, сложении. Например, одна вариация, известная как DLN (Decrement and jump if not zero), имеет только два операнда и использует декремент в качестве базовой операции. Для получения дополнительной информации см. производные языки Subleq [1].
Инструкция SBNZ a, b, c, d
(« вычесть и перейти, если не равно нулю ») вычитает содержимое по адресу a из содержимого по адресу b , сохраняет результат по адресу c , а затем, если результат не равен 0 , передает управление по адресу d (если результат равен нулю, выполнение переходит к следующей инструкции в последовательности). [3]
Инструкция subleq (« вычесть и перейти, если меньше или равно нулю ») вычитает содержимое по адресу a из содержимого по адресу b , сохраняет результат по адресу b , а затем, если результат не положительный , передает управление по адресу c (если результат положительный, выполнение переходит к следующей инструкции в последовательности). [3] : 4–7 Псевдокод :
Инструкция subleq a, b, c
Мем[б] = Мем[б] - Мем[а] если (Mem[b] ≤ 0) перейти к c
Условное ветвление можно подавить, установив третий операнд равным адресу следующей инструкции в последовательности. Если третий операнд не записан, это подавление подразумевается.
Возможен также вариант с двумя операндами и внутренним аккумулятором , где аккумулятор вычитается из ячейки памяти, указанной первым операндом. Результат сохраняется как в аккумуляторе, так и в ячейке памяти, а второй операнд указывает адрес перехода:
Инструкция subleq2 a, b
Мем[а] = Мем[а] - АККУМУЛ АККУМУЛ = Мем[а] если (Mem[a] ≤ 0) перейти к b
Хотя здесь используются только два (вместо трех) операнда на инструкцию, соответственно, для выполнения различных логических операций требуется больше инструкций.
Можно синтезировать много типов инструкций высшего порядка, используя только инструкцию subleq . [3] : 9–10
Безусловный переход:
подзаголовок Z , Z , c
Сложение может быть выполнено путем повторного вычитания без условного ветвления; например, следующие инструкции приводят к тому, что содержимое в местоположении a добавляется к содержимому в местоположении b :
подзаголовок a , Z подзаголовок Z , b подзаголовок Z , Z
Первая инструкция вычитает содержимое в ячейке a из содержимого в ячейке Z (которое равно 0) и сохраняет результат (который является отрицательным значением содержимого в ячейке a ) в ячейке Z. Вторая инструкция вычитает этот результат из b , сохраняя в b эту разницу (которая теперь является суммой содержимого, изначально находившегося в a и b ) ; третья инструкция восстанавливает значение 0 в Z.
Инструкция копирования может быть реализована аналогичным образом; например, следующие инструкции приводят к замене содержимого в местоположении b содержимым в местоположении a , снова предполагая, что содержимое в местоположении Z сохраняется равным 0:
подзаголовок b , b подзаголовок a , Z подзаголовок Z , b подзаголовок Z , Z
Можно построить любой желаемый арифметический тест. Например, условие «ветвь-если-ноль» можно собрать из следующих инструкций:
подзаголовок b , Z , L1 подзаголовок Z , Z , OUT L1: подзаголовок Z , Z подзаголовок Z , b , c OUT: ...
Subleq2 также может использоваться для синтеза инструкций более высокого порядка, хотя обычно для данной задачи требуется больше операций. Например, для переворота всех битов в данном байте требуется не менее 10 инструкций subleq2:
subleq2 tmp ; tmp = 0 (tmp = временный регистр) subleq2 tmp subleq2 one ; acc = -1 subleq2 a ; a' = a + 1 subleq2 Z ; Z = - a - 1 subleq2 tmp ; tmp = a + 1 subleq2 a ; a' = 0 subleq2 tmp ; загрузить tmp в acc subleq2 a ; a' = - a - 1 ( = ~a ) subleq2 Z ; установить Z обратно в 0
Следующая программа (написанная на псевдокоде ) эмулирует выполнение OISC на основе subleq :
int memory [], program_counter , a , b , c program_counter = 0 while ( program_counter >= 0 ) : a = memory [ program_counter ] b = memory [ program_counter + 1 ] c = memory [ program_counter + 2 ] if ( a < 0 or b < 0 ) : program_counter = -1 else : memory [ b ] = memory [ b ] - memory [ a ] if ( memory [ b ] > 0 ) : program_counter += 3 else : program_counter = c
Эта программа предполагает, что memory[] индексируется неотрицательными целыми числами. Следовательно, для инструкции subleq ( a , b , c ) программа интерпретирует a < 0 , b < 0 или выполненный переход к c < 0 как условие остановки. Похожие интерпретаторы, написанные на языке, основанном на subleq (т. е. самоинтерпретаторы , которые могут использовать самомодифицирующийся код , как это допускается природой инструкции subleq ), можно найти по внешним ссылкам ниже.
Универсальная 64-битная операционная система с поддержкой SMP под названием Dawn OS была реализована в эмулируемой машине Subleq. Операционная система содержит компилятор, подобный C. Некоторые области памяти в виртуальной машине используются для периферийных устройств, таких как клавиатура, мышь, жесткие диски, сетевая карта и т. д. Базовые приложения, написанные для нее, включают медиаплеер, инструмент для рисования, считыватель документов и научный калькулятор. [13]
32-битный компьютер Subleq с графическим дисплеем и клавиатурой под названием Ижора был создан Йоэлем Матвеевым в качестве большой модели клеточной автоматизации . [14] [15]
Существует компилятор Higher Subleq, написанный Олегом Мазонкой, который компилирует упрощенную программу на языке C в код subleq . [16]
В качестве альтернативы существует самостоятельная реализация Forth , написанная Ричардом Джеймсом Хоу, которая работает поверх Subleq VM и способна к интерактивному программированию машины Subleq [17]
Инструкция subneg (« вычитание и переход, если отрицательно »), также называемая SBN , определяется аналогично subleq : [2] : 41, 51–52
Инструкция subneg a, b, c
Мем[б] = Мем[б] - Мем[а] если (Mem[b] < 0) перейти к c
Условное ветвление можно подавить, установив третий операнд равным адресу следующей инструкции в последовательности. Если третий операнд не записан, это подавление подразумевается.
Можно синтезировать много типов инструкций высшего порядка, используя только инструкцию subneg . Для простоты здесь показана только одна синтезированная инструкция, чтобы проиллюстрировать разницу между subleq и subneg .
Безусловный переход: [2] : 88–89
подотрицательный POS , Z , c
где Z и POS — местоположения, ранее заданные как содержащие 0 и положительное целое число соответственно;
Безусловное ветвление гарантируется только в том случае, если Z изначально содержит 0 (или значение, меньшее целого числа, хранящегося в POS ). Последующая инструкция необходима для очистки Z после ветвления, при условии, что содержимое Z должно поддерживаться равным 0.
Возможен также вариант с четырьмя операндами – subneg4. Инверсия уменьшаемого и вычитаемого упрощает реализацию в оборудовании. Неразрушающий результат упрощает синтетические инструкции.
Инструкция (* вычитаемое, уменьшаемое, результат и адреса перехода *)subneg s, m, r, j
Мем[р] = Мем[м] - Мем[с] если (Mem[r] < 0) перейти к j
В попытке сделать машину Тьюринга более интуитивной, ZA Melzak рассматривает задачу вычисления с положительными числами. Машина имеет бесконечные счеты, бесконечное количество фишек (камешки, счетные палочки) изначально в специальном месте S. Машина может выполнять одну операцию:
Возьмите из ячейки X столько же фишек, сколько их в ячейке Y, перенесите их в ячейку Z и приступайте к инструкции y.
Если эта операция невозможна из-за недостатка фишек в X, то оставьте счеты как есть и перейдите к инструкции n. [18]
Чтобы все числа оставались положительными и имитировать работу человека-оператора, выполняющего вычисления на реальных счетах, тест выполняется перед любым вычитанием. Псевдокод:
Инструкция if (Mem[X] < Mem[Y]) goto nmelzak X, Y, Z, n, y
Память[X] -= Память[Y] Мем[Z] += Мем[Y] перейти к y
Предоставив несколько программ: умножение, НОД, вычисление n -го простого числа, представление произвольного числа в системе счисления с основанием b , сортировка по порядку величины, Мелзак наглядно показывает, как смоделировать произвольную машину Тьюринга на своей арифметической машине.
умножить: melzak P , ONE , S , stop ; Переместить 1 счетчик из P в S. Если невозможно, перейти к остановке. melzak S , Q , ANS , умножить , умножить ; Переместить q счетчиков из S в ANS. Перейти к первой инструкции. stop:
где ячейка памяти P равна p , Q равна q , ONE равен 1, ANS изначально равен 0 и в конце pq , а S — большое число.
Он упоминает, что можно легко показать, используя элементы рекурсивных функций, что каждое число, вычисляемое на арифметической машине, вычислимо. Доказательство этого было дано Ламбеком [19] на эквивалентной машине с двумя инструкциями: X+ (увеличение X) и X−, иначе T (уменьшение X, если он не пуст, иначе переход к T).
В инструкции обратного вычитания и пропуска , если заем (RSSB) аккумулятор вычитается из ячейки памяти, и следующая инструкция пропускается, если был заем (ячейка памяти была меньше аккумулятора). Результат сохраняется как в аккумуляторе, так и в ячейке памяти. Счетчик программ отображается в ячейку памяти 0. Аккумулятор отображается в ячейку памяти 1. [2]
Инструкция rssb x
АККУМ = Память[x] - АККУМ Мем[x] = АККУМУЛ если (ACCUM < 0) перейти к ПК + 2
Чтобы установить x равным значению y минус z:
# Сначала переместите z в место назначения x. RSSB temp # Для очистки acc, temp требуются три инструкции [См. Примечание 1] RSSB temp RSSB temp RSSB x # Две инструкции очищают acc, x, так как acc уже очищен RSSB x RSSB y # Загрузка y в acc: без заимствования RSSB temp # Сохранение -y в acc, temp: всегда заимствовать и пропускать RSSB temp # Пропущено RSSB x # Сохранение y в x, acc # Во-вторых, выполните операцию. RSSB temp # Для очистки acc, temp требуются три инструкции RSSB temp RSSB temp RSSB z # Загрузка z RSSB x # x = y - z [См. Примечание 2]
Архитектура с транспортным запуском использует только инструкцию перемещения , поэтому изначально она называлась «машиной перемещения». Эта инструкция перемещает содержимое одной ячейки памяти в другую ячейку памяти, объединяя ее с текущим содержимым новой ячейки: [2] : 42 [20]
Инструкция (также пишется a -> b )movx a, b
OP = GetOperation(Mem[ b ]) Mem[ b ] := OP(Mem[ a ], Mem[ b ])
Выполняемая операция определяется целевой ячейкой памяти. Некоторые ячейки специализируются на сложении, некоторые на умножении и т. д. Таким образом, ячейки памяти не являются простым хранилищем, а связаны с арифметико-логическим устройством (АЛУ), настроенным на выполнение только одного вида операций с текущим значением ячейки. Некоторые из ячеек являются инструкциями потока управления для изменения выполнения программы с помощью переходов, условного выполнения , подпрограмм , if-then-else , for-loop и т. д.
Разработан коммерческий микроконтроллер с архитектурой транспортного триггера под названием MAXQ, который скрывает очевидное неудобство OISC с помощью «карты передачи», которая представляет все возможные пункты назначения для инструкций перемещения . [21]
Cryptoleq [22] — язык, похожий на Subleq. Он состоит из одной одноименной инструкции и способен выполнять вычисления общего назначения в зашифрованных программах. Cryptoleq работает с непрерывными ячейками памяти, используя прямую и косвенную адресацию, и выполняет две операции O 1 и O 2 над тремя значениями A, B и C:
Инструкция Mem[b] = O 1 (Mem[a], Mem[b]) , если O 2 (Mem[b]) ≤ 0cryptoleq a, b, c
ИП = с еще ИП = ИП + 3
где a, b и c адресуются указателем инструкции IP, при этом значение IP адресует a, IP + 1 указывает на b, а IP + 2 на c.
В Cryptoleq операции O 1 и O 2 определяются следующим образом:
Главное отличие от Subleq заключается в том, что в Subleq O 1 ( x,y ) просто вычитает y из x , а O 2 ( x ) равно x . Cryptoleq также гомоморфен Subleq, модульная инверсия и умножение гомоморфны вычитанию, а операция O 2 соответствует тесту Subleq, если значения не были зашифрованы. Программа, написанная в Subleq, может работать на машине Cryptoleq, что означает обратную совместимость. Однако Cryptoleq реализует полностью гомоморфные вычисления и может выполнять умножения. Умножение на зашифрованном домене осуществляется с помощью уникальной функции G, которая, как предполагается, трудно поддается обратному проектированию и позволяет повторно зашифровать значение на основе операции O 2 :
где — повторно зашифрованное значение y , а — зашифрованный ноль. x — зашифрованное значение переменной, пусть это будет m , и равно .
Алгоритм умножения основан на сложении и вычитании, использует функцию G и не имеет условных переходов и ветвлений. Шифрование Cryptoleq основано на криптосистеме Paillier .