stringtranslate.com

Маленький человечек-компьютер

Это изображение представляет собой снимок экрана компьютерной программы Little Man. Цвет фона — яркий фиолетовый, в левом верхнем углу название программы написано белым текстом «Компьютерное моделирование маленького человека». Ниже находится таблица данных со столбцами с такими именами, как «строка», «метка», «оператор» и «операнд». В нем лежат различные компьютерные команды, такие как «старт», «цикл», «конец», «число», «ноль». Центр изображения занимает изображение различных частей компьютера, соединенных синими линиями на розовом фоне. Различные части компьютера имеют разные формы и названия, например, оранжевый прямоугольник с надписью «PC» или зеленая буква «V» с надписью «ALU». Справа от него находится черно-серая таблица под названием «ПАМЯТЬ», заполненная различными цифрами, предположительно собранными в ходе работы машины. Наконец, ниже находится панель, где пользователь может вводить «входные данные» для получения «выходных данных» - это рядом с другим полем под названием «консоль», которое записывает работу машины, например «СБОРКА: ПОСТРОЕННАЯ ТАБЛИЦА СИМВОЛОВ».
Компьютерный симулятор маленького человека

Компьютер Little Man ( LMC ) — это учебная модель компьютера , созданная доктором Стюартом Мэдником в 1965 году. [1] LMC обычно используется для обучения студентов, поскольку он моделирует простой компьютер с архитектурой фон Неймана , который имеет все основные возможности современного компьютера. Его можно запрограммировать в машинном коде (хотя и в десятичном, а не в двоичном формате) или ассемблерном коде. [2] [3] [4]

Модель LMC основана на концепции маленького человечка, запертого в закрытой почтовой комнате (аналог компьютера в этом сценарии). В одном конце комнаты есть 100 почтовых ящиков ( память ), пронумерованных от 0 до 99, каждый из которых может содержать трехзначную инструкцию или данные (в диапазоне от 000 до 999). Кроме того, на другом конце есть два почтовых ящика с надписью INBOX и OUTBOX , которые используются для приема и вывода данных. В центре комнаты находится рабочая зона, содержащая простой калькулятор с двумя функциями (сложение и вычитание), известный как аккумулятор , и сбрасываемый счетчик, известный как программный счетчик. Счетчик программ хранит адрес следующей инструкции, которую Маленький Человечек выполнит. Этот счетчик программ обычно увеличивается на 1 после выполнения каждой инструкции, что позволяет маленькому человечку последовательно выполнять программу. Инструкции ветвления позволяют включать в программу итерации (циклы) и структуры условного программирования. Последнее достигается путем установки счетчика программ на непоследовательный адрес памяти, если выполняется определенное условие (обычно значение, хранящееся в аккумуляторе, равно нулю или положительному).

Согласно архитектуре фон Неймана , любой почтовый ящик (обозначающий уникальную ячейку памяти) может содержать либо инструкцию, либо данные. Поэтому необходимо позаботиться о том, чтобы счетчик программ не достиг адреса памяти, содержащего данные, иначе Маленький Человечек попытается воспринять это как инструкцию. Этим можно воспользоваться, записав в почтовые ящики инструкции, предназначенные для интерпретации как кода, для создания самомодифицирующегося кода. Чтобы использовать LMC, пользователь загружает данные в почтовые ящики, а затем дает сигнал «Маленькому человечку» начать выполнение, начиная с инструкции, хранящейся по нулевому адресу памяти. Сброс счетчика программ на ноль фактически перезапускает программу, хотя и в потенциально другом состоянии.

Цикл выполнения

Чтобы выполнить программу, человечек выполняет следующие действия:

  1. Проверьте счетчик программ на наличие номера почтового ящика, содержащего инструкцию программы (т. е. ноль в начале программы).
  2. Получите инструкцию из почтового ящика с этим номером. Каждая инструкция содержит два поля: код операции (указывает операцию, которую необходимо выполнить) и поле адреса (указывает, где найти данные для выполнения операции).
  3. Увеличьте счетчик программ (чтобы он содержал номер почтового ящика следующей инструкции)
  4. Расшифруйте инструкцию. Если инструкция использует данные, хранящиеся в другом почтовом ящике, используйте поле адреса, чтобы найти номер почтового ящика для данных, с которыми она будет работать, например «получить данные из почтового ящика 42»).
  5. Получить данные (из входа, аккумулятора или почтового ящика с адресом, определенным на шаге 4)
  6. Выполнить инструкцию на основе заданного кода операции
  7. Разветвить или сохранить результат (в выходных данных, аккумуляторе или почтовом ящике с адресом, определенным на шаге 4).
  8. Вернитесь к счетчику программ, чтобы повторить цикл или остановиться.

Команды

Хотя LMC действительно отражает фактическую работу двоичных процессоров, простота десятичных чисел была выбрана, чтобы минимизировать сложность для студентов, которым может быть неудобно работать в двоичных/ шестнадцатеричных числах .

инструкции

Некоторые симуляторы LMC программируются напрямую с использованием трехзначных числовых инструкций, а некоторые используют трехбуквенные мнемонические коды и метки. В любом случае набор инструкций намеренно очень ограничен (обычно около десяти инструкций), чтобы упростить понимание. Если LMC использует мнемонические коды и метки, то при сборке программы они преобразуются в трехзначные числовые инструкции.

В таблице ниже показан типичный набор числовых команд и эквивалентные мнемонические коды.

Примеры

Использование числовых кодов инструкций

Эта программа (инструкции с 901 по 000 ) написана только с использованием числовых кодов. Программа принимает на вход два числа и выводит разницу. Обратите внимание, что выполнение начинается в почтовом ящике 00 и заканчивается в почтовом ящике 07. Недостатки программирования LMC с использованием числовых кодов команд обсуждаются ниже.

Использование мнемоники и меток

Язык ассемблера — это язык программирования низкого уровня, в котором вместо числовых кодов команд используются мнемоники и метки. Хотя LMC использует лишь ограниченный набор мнемокодов, удобство использования мнемоники для каждой инструкции становится очевидным из ассемблера той же программы, показанного ниже: программисту больше не требуется запоминать набор анонимных числовых кодов, и он может теперь программа с набором более запоминающихся мнемонических кодов. Если мнемоника представляет собой инструкцию, которая включает адрес памяти ( либо инструкцию ветвления, либо загрузку/сохранение данных ), то для обозначения адреса памяти используется метка.

ИЯФСТА ПЕРВЫЙИЯФСТА ВТОРАЯЛДА ПЕРВЫЙПОД ВТОРОЙВНЕHLTПЕРВЫЙ ДАТВТОРОЙ ДАТ

Этикетки

Без меток программисту придется вручную рассчитывать адреса почтовых ящиков ( памяти ). В примере с числовым кодом , если новая инструкция должна быть вставлена ​​перед последней инструкцией HLT, то эта инструкция HLT переместится с адреса 07 на адрес 08 (маркировка адреса начинается с адреса 00). Предположим, что пользователь ввел 600 в качестве первого ввода. Инструкция 308 будет означать, что это значение будет сохранено по адресу 08 и перезапишет инструкцию 000 (HLT). Поскольку 600 означает «перейти к почтовому ящику с адресом 00», программа вместо остановки застрянет в бесконечном цикле.

Чтобы обойти эту трудность, большинство языков ассемблера ( включая LMC ) комбинируют мнемонику с метками . Метка — это просто слово, которое используется либо для обозначения адреса памяти, где хранится инструкция или данные, либо для ссылки на этот адрес в инструкции.

Когда программа собрана:

В примере на ассемблере , где используются мнемоники и метки, если новая инструкция была вставлена ​​перед последней инструкцией HLT, то адрес, помеченный как FIRST, теперь будет находиться в ячейке памяти 09, а не в 08, и инструкция STA FIRST будет преобразована в 309 (STA 09), а не 308 (STA 08) при сборке программы.

Таким образом, этикетки используются для:

Пример

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

 ИЯФ OUT // Инициализация выводаLOOP BRZ QUIT // Пометить этот адрес памяти как LOOP. Если значение аккумулятора равно 0, перейдите к адресу памяти, обозначенному // ПОКИДАТЬ SUB ONE // Вычитаем из аккумулятора значение, хранящееся по адресу ONE. ВНЕ BRA LOOP // Переход (безусловный) к адресу памяти с меткой LOOPQUIT HLT // Пометить этот адрес памяти как QUITONE DAT 1 // Сохраните значение 1 по этому адресу памяти и пометьте его ONE (объявление переменной)

Программа ниже примет введенные пользователем данные, возведет их в квадрат, выведет ответ и затем повторит. Ввод нуля завершит программу.
( Примечание: ввод, результатом которого является значение больше 999, будет иметь неопределенное поведение из-за ограничения LMC на 3-значное число ).

START LDA ZERO // Инициализация для запуска нескольких программ РЕЗУЛЬТАТ СТА СЧЕТ СТА INP // Введенные пользователем данные BRZ END // Переход к END программы, если вход = 0 STA VALUE // Сохраняем введенные данные как VALUELOOP LDA RESULT // Загрузка РЕЗУЛЬТАТА ДОБАВИТЬ ЗНАЧЕНИЕ // Добавить ЗНАЧЕНИЕ, введенное пользователем, в РЕЗУЛЬТАТ STA RESULT // Сохраняем новый РЕЗУЛЬТАТ LDA COUNT // Загрузите COUNT ДОБАВИТЬ ОДИН // Добавить ОДИН к COUNT STA COUNT // Сохраняем новый COUNT SUB VALUE // Вычитаем введенное пользователем значение VALUE из COUNT BRZ ENDLOOP // Если ноль (VALUE было добавлено к RESULT VALUE раз), переход к ENDLOOP BRA LOOP // Переход к LOOP, чтобы продолжить добавление VALUE к RESULTENDLOOP LDA RESULT // Загрузка РЕЗУЛЬТАТА ВЫХОД // Вывод РЕЗУЛЬТАТА BRA START // Переход к 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 ДОБАВИТЬ ОДИН // Добавить ОДИН к COUNT STA COUNT // Сохраняем новый COUNT SUB VALUE // Вычитаем введенное пользователем значение VALUE из COUNT BRZ ENDLOOP // Если ноль (VALUE было добавлено к RESULT VALUE раз), переход к ENDLOOP ...

со следующей версией, которая оценивает VALUE-COUNT вместо COUNT-VALUE, гарантируя, что аккумулятор никогда не опустеет:

 ... LDA COUNT // Загрузите COUNT ДОБАВИТЬ ОДИН // Добавить ОДИН к COUNT STA COUNT // Сохраняем новый COUNT LDA VALUE // Загрузите ЗНАЧЕНИЕ SUB COUNT // Вычитаем COUNT из введенного пользователем значения VALUE BRZ ENDLOOP // Если ноль (VALUE было добавлено к RESULT VALUE раз), переход к ENDLOOP ...

Другой пример — quine , печатающий собственный машинный код (вывод исходного кода невозможен, поскольку буквы не могут быть выведены):

ЗАГРУЗИТЬ LDA 0 // Загрузить позицию 0 в аккумулятор. Эта строка будет изменяться в каждом цикле для загрузки следующих строк в аккумулятор. OUT // Вывод значения аккумулятора. Значением аккумулятора будет только что загруженная строка. SUB ONE // Вычитаем 1 из значения аккумулятора. Это сделано для того, чтобы мы могли выполнить BRZ на следующем этапе, чтобы увидеть, находимся ли мы на последней строке программы. BRZ ONE // Если предыдущее вычитание сделало аккумулятор равным 0 (что означает, что в аккумуляторе было значение 001), то переходим к позиции ONE LDA LOAD // Загрузка позиции ЗАГРУЗКИ в аккумулятор, это подготовка к увеличению цифр адреса для этой позиции ДОБАВИТЬ ОДИН // Увеличить цифры позиции в строке ЗАГРУЗИТЬ. Значение, находящееся в настоящее время в аккумуляторе, если читать его как инструкцию, загрузит в аккумулятор следующую строку по сравнению с последней загруженной строкой. STA LOAD // Сохраняем вновь увеличенную строку LOAD обратно в позицию LOAD ЗАГРУЗКА БРЮКА // Возврат в начало циклаONE DAT 1 // Переменная ONE. Если читать как инструкцию, это будет интерпретировано как HLT/COB и завершит программу.

Этот куайн работает с использованием самомодифицирующегося кода . Позиция 0 увеличивается на единицу в каждой итерации, выводя код этой строки, пока код, который она выводит, не станет равным 1, после чего он переходит в позицию ONE. Значение в позиции ONE имеет 0 в качестве кода операции, поэтому оно интерпретируется как инструкция HALT/COB.

Смотрите также

Рекомендации

  1. ^ "Маленький компьютер-человек" . Государственный университет Иллинойса . 1 мая 2000 года. Архивировано из оригинала 27 февраля 2009 года . Проверено 8 марта 2009 г.
  2. ^ Юрчик, В.; Осборн, Х. (2001). «Толпа маленьких человечков-компьютеров: средства обучения визуальным компьютерным симуляторам». Материалы зимней конференции по моделированию 2001 г. (кат. № 01CH37304) . Том. 2. п. 1632. дои :10.1109/WSC.2001.977496. ISBN 0-7803-7307-3. S2CID  18907923.
  3. ^ Юрчик, В.; Брамбо, Л. (2001). «Компьютерный веб-симулятор маленького человечка». Материалы тридцать второго технического симпозиума SIGCSE по компьютерному образованию - SIGCSE '01 . п. 204. дои : 10.1145/364447.364585. ISBN 1581133294. S2CID  14794750.
  4. ^ Осборн, Х.; Юрчик, В. (2002). «Образовательный диапазон визуального моделирования парадигмы компьютерной архитектуры Little Man». 32-я ежегодная выставка «Границы образования» . стр. S4G–S19. дои : 10.1109/FIE.2002.1158742. ISBN 0-7803-7444-4. S2CID  10324295.

Внешние ссылки

Симуляторы

В сети