Little Man Computer ( LMC ) является учебной моделью из компьютера , созданный доктор Стьюарт Мадника в 1965 г. [1] LMC , как правило , используется для студентов учить, потому что это моделирует простой фон Нейман архитектуры компьютер, который имеет все основные характеристики современного компьютера. Он может быть запрограммирован в машинном коде (хотя и в десятичном, а не в двоичном) или ассемблерном коде. [2] [3] [4]
Модель 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. В противном случае ничего не делайте. Учитывается ли отрицательный флаг, не определено. Когда SUBTRACT опустошает аккумулятор, этот флаг устанавливается, после чего аккумулятор не определен, потенциально равен нулю, в результате чего поведение 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 [5], доступном на веб-сайте Йоркского университета ( Торонто , Онтарио , Канада), или в настольном приложении, написанном Майком Коли. [6] Все эти симуляторы включают полные инструкции и примеры программ, ассемблер для преобразования кода ассемблера в машинный код, интерфейсы управления для выполнения и мониторинга программ, а также пошаговое подробное описание каждой инструкции LMC.
INPSTA FIRSTINPСТА ВТОРОЙLDA ПЕРВЫЙSUB SECONDВНЕHLTПЕРВЫЙ ДАТВТОРАЯ ДАТА
Ярлыки [ править ]
Без меток программист должен вручную вычислять адреса почтовых ящиков ( памяти ). В примере числового кода , если новая инструкция должна быть вставлена перед последней инструкцией HLT, то эта инструкция HLT переместится с адреса 07 на адрес 08 (разметка адреса начинается с адреса 00). Предположим, пользователь ввел 600 в качестве первого ввода. Команда 308 будет означать, что это значение будет сохранено в ячейке адреса 08 и перезапишет команду 000 (HLT). Поскольку 600 означает «переход к адресу почтового ящика 00», программа вместо остановки могла бы застрять в бесконечном цикле.
Чтобы обойти эту трудность, большинство языков ассемблера ( включая LMC ) комбинируют мнемонику с метками . Метка - это просто слово, которое используется либо для обозначения адреса памяти, где хранятся инструкция или данные, либо для ссылки на этот адрес в инструкции.
Когда программа собрана:
- Метка слева от мнемоники инструкции преобразуется в адрес памяти, в котором хранятся инструкция или данные. т.е. loopstart INP
- Метка справа от мнемоники инструкции принимает значение адреса памяти, упомянутого выше. т.е. петля для бюстгальтера
- Метка в сочетании с оператором 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 // Инициализировать вывод LOOP BRZ QUIT // Обозначьте этот адрес памяти как LOOP. Если значение аккумулятора равно 0, перейдите к адресу памяти с меткой QUIT. SUB ONE // Вычесть значение, хранящееся по адресу ONE, из аккумулятора ВНЕ BRA LOOP // Переход (безоговорочно) к адресу памяти, помеченному LOOPQUIT HLT // Обозначьте этот адрес памяти как QUITONE DAT 1 // Сохраняем значение 1 в этом адресе памяти и обозначаем его ONE (объявление переменной)
Программа ниже примет пользовательский ввод, возведет его в квадрат, выведет ответ и затем повторится. Ввод нуля завершит программу.
( Примечание: вход, который приводит к значению больше 999, будет иметь неопределенное поведение из-за ограничения 3-значного числа LMC ).
START LDA ZERO // Инициализировать для запуска нескольких программ STA РЕЗУЛЬТАТ STA COUNT INP // Пользовательский ввод BRZ END // Переход к программе END, если input = 0 STA VALUE // Сохранить ввод как VALUELOOP LDA RESULT // Загрузить РЕЗУЛЬТАТ ДОБАВИТЬ ЗНАЧЕНИЕ // Добавить ЗНАЧЕНИЕ, введенное пользователем, в РЕЗУЛЬТАТ STA RESULT // Сохраните новый РЕЗУЛЬТАТ LDA COUNT // Загрузить COUNT ДОБАВИТЬ ОДИН // Добавить ОДИН в СЧЁТ STA COUNT // Сохранение нового COUNT SUB VALUE // Вычтите введенное пользователем значение VALUE из COUNT BRZ ENDLOOP // Если ноль (ЗНАЧЕНИЕ было добавлено к РЕЗУЛЬТАТУ за ЗНАЧЕНИЕ раз), перейти к КОНТУСУ BRA LOOP // Перейти к LOOP, чтобы продолжить добавление ЗНАЧЕНИЯ к РЕЗУЛЬТАТУENDLOOP LDA RESULT // Загрузить РЕЗУЛЬТАТ OUT // Вывод РЕЗУЛЬТАТА BRA START // Переход к СТАРТу для инициализации и получения другого входного ЗНАЧЕНИЯEND HLT // HALT - был введен ноль, готово!RESULT DAT // Вычисленный результат (по умолчанию 0)COUNT DAT // Счетчик (по умолчанию 0)ONE DAT 1 // Константа, значение 1VALUE DAT // Пользовательский ввод, значение, которое нужно возвести в квадрат (по умолчанию 0)ZERO DAT // Константа, значение 0 (по умолчанию 0)
Примечание. Если после оператора DAT нет данных, то в адресе памяти сохраняется значение по умолчанию 0.
В приведенном выше примере [BRZ ENDLOOP] зависит от неопределенного поведения, так как COUNT-VALUE может быть отрицательным, после чего значение ACCUMULATOR не определено, в результате BRZ либо ветвится, либо нет (ACCUMULATOR может быть равен нулю или закругляться). Чтобы код был совместим со спецификацией, замените:
... LDA COUNT // Загрузить COUNT ДОБАВИТЬ ОДИН // Добавить ОДИН в СЧЁТ STA COUNT // Сохранение нового COUNT SUB VALUE // Вычтите введенное пользователем значение VALUE из COUNT BRZ ENDLOOP // Если ноль (ЗНАЧЕНИЕ было добавлено к РЕЗУЛЬТАТУ за ЗНАЧЕНИЕ раз), перейти к КОНТУСУ ...
со следующей версией, которая оценивает VALUE-COUNT вместо COUNT-VALUE, чтобы аккумулятор никогда не переполнялся:
... LDA COUNT // Загрузить COUNT ДОБАВИТЬ ОДИН // Добавить ОДИН в СЧЁТ STA COUNT // Сохранение нового COUNT LDA VALUE // Загрузить VALUE SUB COUNT // Вычтите COUNT из введенного пользователем значения VALUE BRZ ENDLOOP // Если ноль (ЗНАЧЕНИЕ было добавлено к РЕЗУЛЬТАТУ за ЗНАЧЕНИЕ раз), перейти к КОНТУСУ ...
Другой пример - quine , печатающий собственный машинный код (печать исходного кода невозможна, поскольку буквы не выводятся):
LOAD LDA 0 // Загрузить позицию 0 в аккумулятор. Эта строка будет изменяться в каждом цикле для загрузки следующих строк в аккумулятор. OUT // Вывести значение аккумулятора. Значение аккумулятора будет только что загруженной строкой. SUB ONE // Вычтите 1 из значения в аккумуляторе. Это сделано для того, чтобы мы могли выполнить BRZ на следующем шаге, чтобы увидеть, находимся ли мы на последней строке программы. BRZ ONE // Если предыдущее вычитание сделало аккумулятор 0 (что означает, что у нас было значение 001 в аккумуляторе), затем перейти к позиции ONE LDA LOAD // Загружаем позицию LOAD в аккумулятор, это подготовка к увеличению цифр адреса для этой позиции ДОБАВИТЬ ОДИН // Увеличиваем цифры позиции для строки ЗАГРУЗКИ. Текущее значение в аккумуляторе при чтении в виде инструкции загрузит в аккумулятор следующую строку по сравнению с последней загруженной строкой. STA LOAD // Сохраните вновь увеличенную строку ЗАГРУЗКИ обратно в положение ЗАГРУЗКИ BRA LOAD // Вернуться в начало циклаONE DAT 1 // Переменная ONE. Если читать как инструкцию, это будет интерпретировано как HLT / COB и завершит программу.
Этот quine работает с использованием самомодифицирующегося кода . Позиция 0 увеличивается на единицу в каждой итерации, выводя код этой строки, пока код, который она выводит, не станет 1, после чего она переходит в ОДНУ позицию. Значение в позиции ONE имеет код операции 0, поэтому он интерпретируется как инструкция HALT / COB.
См. Также [ править ]
- CARDboard Иллюстративное пособие по вычислениям (еще одна учебная модель)
- ТИС-100 (видеоигра)
- Human Resource Machine , компьютерная игра, на которую сильно повлияла LMC
Ссылки [ править ]
- ^ "Маленький компьютер человека" . Государственный университет Иллинойса . 1 мая 2000 года Архивировано из оригинального 27 февраля 2009 года . Проверено 8 марта 2009 года .
- ^ Юрчик, W .; Осборн, Х. (2001). «Толпа Little Man Computers: обучающие инструменты на визуальном компьютерном симуляторе». Труды Зимней конференции по моделированию 2001 г. (Кат. № 01CH37304) . 2 . п. 1632. DOI : 10,1109 / WSC.2001.977496 . ISBN 0-7803-7307-3.
- ^ Юрчик, W .; Брамбо, Л. (2001). «Интернет-симулятор маленького человечка». Материалы тридцать второго технического симпозиума SIGCSE по образованию в области компьютерных наук - SIGCSE '01 . п. 204. DOI : 10,1145 / 364447,364585 . ISBN 1581133294.
- ^ Осборн, H .; Юрчик, В. (2002). «Образовательный диапазон визуальных симуляций парадигмы компьютерной архитектуры маленького человека». 32-я ежегодная конференция «Границы образования» . стр. S4G – S19. DOI : 10.1109 / FIE.2002.1158742 . ISBN 0-7803-7444-4.
- ^ Чен, Стивен Ю.; Кадмор, Уильям К. "Маленький компьютер" . Йоркский университет . Проверено 7 октября 2010 года .
- ^ Коли, Майк. "Маленький компьютер" . Проверено 12 апреля 2012 года .
Внешние ссылки [ править ]
- Ричард Дж. Повинелли: Обучение: Введение в компьютерное оборудование и программное обеспечение: Маленький Человек Компьютер
- Компьютер "Маленький человек"
Симуляторы [ править ]
Онлайн [ править ]
- Симулятор LMC Питера Хиггинсона
- Симулятор LMC Пола Ханкина
- Симулятор LMC Тринко
- компанией 101computing
- Симулятор LMC П. Бринкмайера
- Симулятор Робоврайтера LMC
- CPU BattleTanks: управляйте танком в браузере с помощью компьютерного процессора Little Man.
Другое [ править ]
- Пакет Emacs
- Исполняемый файл для Windows по вычислениям GCSE
- Исполняемый файл Windows
- Исполняемый файл Windows
- Исполняемый файл Windows с графическим человечком
- Little Man Computer и Little Robot Computer - упрощенная версия
- Компилятор, ассемблер, дизассемблер, симулятор Дэвида Вейла, написанный на Python