Большинство из этих ответов касаются вопроса, будет ли это практичным. Дэвид Джонстон также упоминает тот факт, что имя регистра должно упоминаться в каждой инструкции, которая к нему относится. В дополнение к этому, в большинстве современных наборов инструкций у команды всегда есть закодированные регистры операндов. Например. есть инструкция mov %eax, %ebx
и инструкция mov %eax, %ecx
. Может случиться так, что их двоичное представление выглядит так:
| mov | source reg | dest reg |
| 2 | 3 | 3 |
и отличается только тем, что dest reg
равно 3, а не 2 - но это также не может! (Я не проверял, как эти конкретные инструкции представлены в 386, но я вспоминаю, что в этом наборе команд есть примеры, которые легко разбиваются на подобные поля, и примеры, где их нет.)
Проблема в том, что наиболее интересным программам захочется работать в местах информации, определенных во время выполнения. Например. в этой итерации цикла мы хотим посмотреть на байт 37; на следующей итерации нас будет интересовать байт 38 и т. д.
Я не буду это доказывать, но я подозреваю, что для того, чтобы что-то приблизилось к полноте по Тьюрингу, вашим программам потребуется либо:
- инструкции, которые адресуют регистры на основе значения в некотором другом регистре, например «Переместиться из регистра X в регистр Y, где X и Y обозначены значениями в регистрах 1 и 2.», или
- самоизменяющийся код.
В школе у нас был теоретический компьютер с 100 регистрами (плюс аккумулятор) и 10 инструкциями, каждая из которых представляла собой трехзначное десятичное число. Первая цифра указывает операцию (загрузка, сохранение, арифметика, переход, условный переход, остановка), а последние два регистра работают с ним. Для этого можно написать множество примеров программ, например, функцию факториала. Но вскоре стало очевидно, что статическая программа может работать только с фиксированным набором данных. Если вы хотите написать цикл для суммирования значений в списке, вам понадобится инструкция LOAD, которая указывает на разные входные регистры на каждой итерации. Это означало, что вы будете арифметически вычислять новый код для инструкции загрузки каждый раз и исправлять код непосредственно перед выполнением этой инструкции.