Маленький компьютер человечек - Little man computer
Little Man Computer ( LMC ) является учебная модель из компьютера , созданного доктором Стьюарт Мадник в 1965 БМО , как правило , используется для студентов учить, потому что моделям простой архитектуры фон Неймана компьютером , который обладает всеми основными функциями современного компьютера. Он может быть запрограммирован в машинном коде (хотя и в десятичном, а не в двоичном) или ассемблерном коде.
Модель LMC основана на концепции маленького человека, запертого в закрытой почтовой комнате (аналог компьютера в этом сценарии). В одном конце комнаты находится 100 почтовых ящиков ( память ), пронумерованных от 0 до 99, каждый из которых может содержать 3-значные инструкции или данные (от 000 до 999). Кроме того, есть два почтовых ящика на другом конце меченого INBOX и OUTBOX , которые используются для приема и вывода данных. В центре комнаты находится рабочая зона, содержащая простой двухфункциональный калькулятор (сложение и вычитание), известный как Накопитель, и сбрасываемый счетчик, известный как Программный счетчик. Счетчик программ содержит адрес следующей инструкции, которую будет выполнять Маленький Человек. Этот Программный Счетчик обычно увеличивается на 1 после выполнения каждой инструкции, что позволяет Маленькому Человеку работать с программой последовательно. Инструкции ветвления позволяют включать в программу итерации (циклы) и структуры условного программирования. Последнее достигается путем установки Программного счетчика на непоследовательный адрес памяти, если выполняется определенное условие (обычно значение, хранящееся в аккумуляторе, равно нулю или положительно).
Как указано в архитектуре фон Неймана , любой почтовый ящик (обозначающий уникальную ячейку памяти) может содержать либо инструкцию, либо данные. Поэтому необходимо следить за тем, чтобы программный счетчик не достиг адреса памяти, содержащей данные, - иначе Маленький Человек попытается обработать это как инструкцию. Этим можно воспользоваться, написав инструкции в почтовые ящики, которые должны интерпретироваться как код, для создания самомодифицирующегося кода. Чтобы использовать ЛКМ, пользователь загружает данные в почтовые ящики, а затем сигнализирует Маленькому Человеку начать выполнение, начиная с инструкции, хранящейся в нулевом адресе памяти. Сброс счетчика программы на ноль эффективно перезапускает программу, хотя и в потенциально другом состоянии.
Цикл исполнения
Чтобы выполнить программу, человечек выполняет следующие действия:
- Проверьте счетчик программ на номер почтового ящика, который содержит инструкцию программы (т.е. ноль в начале программы).
- Получите инструкцию из почтового ящика с этим номером. Каждая инструкция содержит два поля: код операции (указывающий на выполняемую операцию) и поле адреса (указывающее, где найти данные для выполнения операции).
- Увеличьте счетчик программы (так, чтобы он содержал номер почтового ящика следующей инструкции)
- Расшифруйте инструкцию. Если в инструкции используются данные, хранящиеся в другом почтовом ящике, используйте поле адреса, чтобы найти номер почтового ящика для данных, с которыми он будет работать, например, «получить данные из почтового ящика 42»)
- Получите данные (из входа, аккумулятора или почтового ящика с адресом, определенным на шаге 4)
- Выполнить инструкцию на основе заданного кода операции
- Разветвите или сохраните результат (в выводе, накопителе или почтовом ящике с адресом, определенным на шаге 4)
- Вернитесь к счетчику программ, чтобы повторить цикл или остановить
Команды
Хотя LMC действительно отражает фактическую работу двоичных процессоров, была выбрана простота десятичных чисел, чтобы минимизировать сложность для студентов, которым может быть неудобно работать в двоичном / шестнадцатеричном формате .
инструкции
Некоторые симуляторы LMC программируются напрямую с использованием 3-значных числовых команд, а некоторые используют трехбуквенные мнемонические коды и метки. В любом случае набор инструкций намеренно очень ограничен ( обычно около десяти инструкций ), чтобы упростить понимание. Если LMC использует мнемонические коды и метки, то они преобразуются в 3-значные числовые инструкции при сборке программы.
В таблице ниже показан типичный набор числовых команд и эквивалентные мнемонические коды.
Числовой код | Мнемонический код | Инструкция | Описание |
---|---|---|---|
1xx | ДОБАВИТЬ | ДОБАВИТЬ | Добавьте значение, хранящееся в почтовом ящике xx, к любому значению, которое в настоящее время находится в аккумуляторе (калькуляторе).
|
2xx | SUB | ВЫЧИТАТЬ | Вычтите значение, хранящееся в почтовом ящике xx, из любого значения, которое в настоящее время находится в аккумуляторе (калькуляторе).
|
3xx | STA | ХРАНИТЬ | Хранить содержимое аккумулятора в почтовом ящике xx (деструктивно).
|
5xx | LDA | НАГРУЗКА | Загрузите значение из почтового ящика xx (неразрушающее) и введите его в аккумулятор (разрушающее). |
6xx | БЮСТГАЛЬТЕР | ФИЛИАЛ (безусловный) | Установите программный счетчик на заданный адрес (значение xx). То есть значение в почтовом ящике xx будет следующей выполненной инструкцией. |
7xx | BRZ | ФИЛИАЛ, ЕСЛИ НОЛЬ ( условно ) | Если аккумулятор (калькулятор) содержит значение 000, установите программный счетчик на значение xx. В противном случае ничего не делайте. Учитывается ли отрицательный флаг, не определено. Когда СУБТРАКТ опустошает аккумулятор, этот флаг устанавливается, после чего аккумулятор не определен, потенциально равен нулю, что приводит к неопределенному поведению BRZ при недополнении. Предлагаемое поведение - ветвление, если аккумулятор равен нулю и отрицательный флаг не установлен.
|
8xx | BRP | ФИЛИАЛ, ЕСЛИ ПОЛОЖИТЕЛЬНО (условно) | Если аккумулятор (калькулятор) равен 0 или положителен, установите программный счетчик на значение xx. В противном случае ничего не делайте. Так как ячейки памяти LMC могут содержать только значения от 0 до 999, эта инструкция зависит исключительно от отрицательного флага, установленного потерей значимости в SUBTRACT и, возможно, от переполнения в ADD (undefined).
|
901 | INP | ВХОД | Зайдите во INBOX, получите значение от пользователя и поместите его в аккумулятор (калькулятор)
|
902 | ИЗ | ВЫХОД | Скопируйте значение из аккумулятора (калькулятора) в OUTBOX.
|
000 | HLT / COB | HALT / COFFEE BREAK | Прекратить работу / завершить программу. |
DAT | ДАННЫЕ | Это инструкция ассемблера, которая просто загружает значение в следующий доступный почтовый ящик. DAT также можно использовать вместе с метками для объявления переменных. Например, DAT 984 сохранит значение 984 в почтовом ящике по адресу инструкции DAT. |
Примеры
Использование цифровых кодов инструкций
Эта программа (от инструкций 901 до инструкции 000 ) написана только с использованием числовых кодов. Программа принимает на вход два числа и выводит разницу. Обратите внимание, что выполнение начинается в почтовом ящике 00 и заканчивается в почтовом ящике 07. Недостатки программирования LMC с использованием числовых кодов команд обсуждаются ниже.
Почтовый ящик | Числовой код | Операция | Комментарии |
---|---|---|---|
00 | 901 | ВХОДНОЙ ЯЩИК -> АККУМУЛЯТОР | ВВЕДИТЕ первое число, введите в калькулятор (стирая все, что там было) |
01 | 308 | АККУМУЛЯТОР -> ПАМЯТЬ [08] | СОХРАНИТЬ текущее значение калькулятора (чтобы подготовиться к следующему шагу ...) |
02 | 901 | ВХОДНОЙ ЯЩИК -> АККУМУЛЯТОР | ВВЕДИТЕ второе число, введите в калькулятор (стирая все, что там было) |
03 | 309 | АККУМУЛЯТОР -> ПАМЯТЬ [09] | СОХРАНИТЕ текущее значение калькулятора (опять же, чтобы подготовиться к следующему шагу ...) |
04 | 508 | ПАМЯТЬ [08] -> АККУМУЛЯТОР | (Теперь, когда оба значения INPUT хранятся в почтовых ящиках 08 и 09 ...)
ЗАГРУЗИТЕ первое значение обратно в калькулятор (удалив все, что там было) |
05 | 209 | АККУМУЛЯТОР = АККУМУЛЯТОР - ПАМЯТЬ [09] | ВЫЧИТАЙТЕ второе число из текущего значения калькулятора (которое было только что установлено на первое число) |
06 | 902 | АККУМУЛЯТОР -> ВЫХОДНОЙ ЯЩИК | ВЫВОДИТЕ результат калькулятора в OUTBOX |
07 | 000 | (операция не выполняется) | ОСТАНОВИТЬ БМО |
Использование мнемоники и меток
Ассемблер - это язык программирования низкого уровня, который использует мнемонику и метки вместо числовых кодов инструкций. Хотя LMC использует только ограниченный набор мнемоник, удобство использования мнемоники для каждой инструкции становится очевидным из языка ассемблера той же программы, показанной ниже - программисту больше не требуется запоминать набор анонимных числовых кодов и он может Теперь программа с набором более запоминающихся мнемонических кодов. Если мнемоника - это инструкция, которая включает в себя адрес памяти ( либо инструкцию ветвления, либо загрузку / сохранение данных ), тогда для имени адреса памяти используется метка.
- Этот пример программы можно скомпилировать и запустить на симуляторе LMC, доступном на веб-сайте Йоркского университета ( Торонто , Онтарио , Канада), или в настольном приложении, написанном Майком Коли. Все эти симуляторы включают полные инструкции и примеры программ, ассемблер для преобразования кода сборки в машинный код, интерфейсы управления для выполнения и мониторинга программ, а также пошаговое подробное описание каждой инструкции LMC.
INP STA FIRST INP STA SECOND LDA FIRST SUB SECOND OUT HLT FIRST DAT SECOND DAT
Этикетки
Без меток программист должен вручную вычислять адреса почтовых ящиков ( памяти ). В примере числового кода , если новая инструкция должна быть вставлена перед последней инструкцией HLT, то эта инструкция HLT переместится с адреса 07 на адрес 08 (разметка адреса начинается с адреса 00). Предположим, пользователь ввел 600 в качестве первого ввода. Команда 308 будет означать, что это значение будет сохранено в ячейке адреса 08 и перезапишет команду 000 (HLT). Поскольку 600 означает «переход к адресу почтового ящика 00», программа вместо остановки могла бы застрять в бесконечном цикле.
Чтобы обойти эту трудность, большинство языков ассемблера ( включая LMC ) комбинируют мнемонику с метками . Метка - это просто слово, которое используется либо для обозначения адреса памяти, где хранятся инструкция или данные, либо для ссылки на этот адрес в инструкции.
Когда программа собрана:
- Метка слева от мнемоники инструкции преобразуется в адрес памяти, в котором хранятся инструкция или данные. т.е. loopstart INP
- Метка справа от мнемоники инструкции принимает значение адреса памяти, упомянутого выше. т.е. петля BRA
- Метка в сочетании с оператором DAT работает как переменная, она маркирует адрес памяти, в котором хранятся данные. т.е. один DAT 1 или номер 1 DAT
В примере на языке ассемблера, который использует мнемонику и метки, если новая инструкция была вставлена перед последней инструкцией HLT, то адрес, помеченный как FIRST, теперь будет в ячейке памяти 09, а не 08, и инструкция STA FIRST будет преобразована в 309 (STA 09), а не 308 (STA 08) при сборке программы.
Поэтому ярлыки используются для:
- идентифицировать конкретную инструкцию как цель для инструкции BRANCH.
- идентифицировать ячейку памяти как именованную переменную (используя DAT) и, при необходимости, загружать данные в программу во время сборки для использования программой (это использование неочевидно, пока не будет принято во внимание, что нет способа добавить 1 к счетчику. попросите пользователя ввести 1 в начале, но было бы лучше, чтобы это было загружено во время сборки с использованием одного DAT 1 )
Пример
Программа ниже примет пользовательский ввод и обратный отсчет до нуля.
INP OUT // Initialize output LOOP BRZ QUIT // Label this memory address as LOOP. If the accumulator value is 0, jump to the memory address labeled QUIT SUB ONE // Subtract the value stored at address ONE from the accumulator OUT BRA LOOP // Jump (unconditionally) to the memory address labeled LOOP QUIT HLT // Label this memory address as QUIT ONE DAT 1 // Store the value 1 in this memory address, and label it ONE (variable declaration)
Программа ниже примет пользовательский ввод, возведет его в квадрат, выведет ответ и затем повторится. Ввод нуля завершит программу.
( Примечание: вход, который приводит к значению больше 999, будет иметь неопределенное поведение из-за ограничения 3-значного числа LMC ).
START LDA ZERO // Initialize for multiple program run STA RESULT STA COUNT INP // User provided input BRZ END // Branch to program END if input = 0 STA VALUE // Store input as VALUE LOOP LDA RESULT // Load the RESULT ADD VALUE // Add VALUE, the user provided input, to RESULT STA RESULT // Store the new RESULT LDA COUNT // Load the COUNT ADD ONE // Add ONE to the COUNT STA COUNT // Store the new COUNT SUB VALUE // Subtract the user provided input VALUE from COUNT BRZ ENDLOOP // If zero (VALUE has been added to RESULT by VALUE times), branch to ENDLOOP BRA LOOP // Branch to LOOP to continue adding VALUE to RESULT ENDLOOP LDA RESULT // Load RESULT OUT // Output RESULT BRA START // Branch to the START to initialize and get another input VALUE END HLT // HALT - a zero was entered so done! RESULT DAT // Computed result (defaults to 0) COUNT DAT // Counter (defaults to 0) ONE DAT 1 // Constant, value of 1 VALUE DAT // User provided input, the value to be squared (defaults to 0) ZERO DAT // Constant, value of 0 (defaults to 0)
Примечание. Если после оператора DAT нет данных, то в адресе памяти сохраняется значение по умолчанию 0.
В приведенном выше примере [BRZ ENDLOOP] зависит от неопределенного поведения, так как COUNT-VALUE может быть отрицательным, после чего значение ACCUMULATOR не определено, в результате BRZ либо ветвится, либо нет (ACCUMULATOR может быть равен нулю или закругляться). Чтобы код был совместим со спецификацией, замените:
... LDA COUNT // Load the COUNT ADD ONE // Add ONE to the COUNT STA COUNT // Store the new COUNT SUB VALUE // Subtract the user provided input VALUE from COUNT BRZ ENDLOOP // If zero (VALUE has been added to RESULT by VALUE times), branch to ENDLOOP ...
со следующей версией, которая оценивает VALUE-COUNT вместо COUNT-VALUE, чтобы аккумулятор никогда не переполнялся:
... LDA COUNT // Load the COUNT ADD ONE // Add ONE to the COUNT STA COUNT // Store the new COUNT LDA VALUE // Load the VALUE SUB COUNT // Subtract COUNT from the user provided input VALUE BRZ ENDLOOP // If zero (VALUE has been added to RESULT by VALUE times), branch to ENDLOOP ...
Другой пример - quine , печатающий собственный машинный код (печать исходного кода невозможна, поскольку буквы не выводятся):
LOAD LDA 0 // Load position 0 into the accumulator. This line will be modified on each loop to load the next lines into the accumulator OUT // Output the accumulator's value. The accumulator's value will be the line that was just loaded SUB ONE // Subtract 1 from the value in the accumulator. This is so we can do the BRZ in the next step to see if we are on the last line in the program BRZ ONE // If the previous subtraction has made the accumulator 0 (which means we had the value 001 in the accumulator), then branch to position ONE LDA LOAD // Load the LOAD position into the accumulator, this is in preparation to increment the address digits for this position ADD ONE // Increment the position digits for the LOAD line. The value currently in the accumulator would, if read as an instruction, load the next line into the accumulator, compared to the last line loaded STA LOAD // Store the newly incremented LOAD line back in the LOAD position BRA LOAD // Return to the beginning of the loop ONE DAT 1 // The variable ONE. If read as an instruction, this will be interpreted as HLT/COB and will end the program
Этот quine работает с использованием самомодифицирующегося кода . Позиция 0 увеличивается на единицу в каждой итерации, выводя код этой строки, пока код, который она выводит, не станет 1, после чего она переходит в ОДНУ позицию. Значение в позиции ONE имеет код операции 0, поэтому он интерпретируется как инструкция HALT / COB.
Смотрите также
- CARDboard Иллюстративное пособие по вычислениям (еще одна учебная модель)
- ТИС-100 (видеоигра)
- Human Resource Machine , компьютерная игра, на которую сильно повлияла LMC
использованная литература
внешние ссылки
- Ричард Дж. Повинелли: Обучение: Введение в компьютерное оборудование и программное обеспечение: Маленький Человек Компьютер
- Компьютер "Маленький человек"
Симуляторы
онлайн
- Симулятор LMC Питера Хиггинсона
- Симулятор LMC Пола Ханкина
- Симулятор LMC Тринко
- компанией 101computing
- Симулятор LMC П. Бринкмайера
- Симулятор Робоврайтера LMC
- CPU BattleTanks: управляйте танком в браузере с помощью компьютерного процессора Little Man.
Другой
- Пакет Emacs
- Исполняемый файл для Windows по вычислениям GCSE
- Исполняемый файл Windows
- Исполняемый файл Windows
- Исполняемый файл Windows с графическим человечком
- Little Man Computer и Little Robot Computer - упрощенная версия
- Компилятор, ассемблер, дизассемблер, симулятор Дэвида Вейла, написанный на Python