mini|hochkant=1.5|Little Man Computer Simulator LMC|alternativtext=Wellingborough School - Little Man Computer Simulator

Der Little Man Computer (LMC) ist ein Modell zur besseren Erklärung der Von-Neumann-Architektur, das im Jahr 1965 von Stuart Madnick entwickelt worden ist.

Das Modell stellt die grundlegenden Funktionen eines Computers verständlich und spielerisch dar und kann sowohl in Maschinen- als auch in Assemblersprache programmiert werden. Zur Zielgruppe gehören insbesondere Schüler und Studenten.

Das LMC-Modell basiert auf dem Konzept eines kleinen Mannes, der in einer geschlossenen Poststelle eingesperrt ist (analog zu einem Computer in diesem Szenario). An einem Ende des Raums befinden sich 100 Mailboxen (Speicher), die von 0 bis 99 nummeriert sind und jeweils eine dreistellige Anweisung oder Daten (im Bereich von 000 bis 999) enthalten können. Darüber hinaus befinden sich am anderen Ende zwei Postfächer mit der Bezeichnung INBOX und OUTBOX, die dem Empfang und der Ausgabe von Daten dienen. In der Mitte des Raumes befindet sich ein Arbeitsbereich mit einem einfachen Rechner mit zwei Funktionen (Addition und Subtraktion), der als Akkumulator bekannt ist, und einem rücksetzbaren Zähler, der als Programmzähler bekannt ist. Der Programmzähler speichert die Adresse der nächsten Anweisung, die der kleine Mann ausführen wird. Dieser Programmzähler wird normalerweise nach der Ausführung jeder Anweisung um 1 erhöht, sodass der kleine Mann ein Programm sequentiell abarbeiten kann. Verzweigungsanweisungen ermöglichen die Integration von Iterationen (Schleifen) und bedingten Programmierstrukturen in ein Programm. Letzteres wird dadurch erreicht, dass der Programmzähler auf eine nichtsequentielle Speicheradresse gesetzt wird, wenn eine bestimmte Bedingung erfüllt ist (normalerweise ist der im Akkumulator gespeicherte Wert Null oder positiv).

Gemäß der von Neumann-Architektur kann jedes Postfach (was einen eindeutigen Speicherort bedeutet) entweder eine Anweisung oder Daten enthalten. Daher muss darauf geachtet werden, dass der Programmzähler nicht eine Speicheradresse erreicht, die Daten enthält – sonst versucht der kleine Mann, sie als Anweisung zu behandeln. Dies kann man sich zunutze machen, indem man Anweisungen in Mailboxen schreibt, die als Code interpretiert werden sollen, um selbstmodifizierenden Code zu erstellen. Um die LMC zu verwenden, lädt der Benutzer Daten in die Mailboxen und signalisiert dann dem kleinen Mann, mit der Ausführung zu beginnen, beginnend mit der Anweisung, die an der Speicheradresse Null gespeichert ist. Durch das Zurücksetzen des Programmzählers auf Null wird das Programm effektiv neu gestartet, wenn auch in einem möglicherweise anderen Zustand.

Ausführungsschritte

Um ein Programm auszuführen, werden folgende Schritte durchlaufen:

Überprüfen des Programmzählers auf die Registeradresse, die eine Programmanweisung enthält (d. h. Null beim Start des Programms). Holen der Anweisung aus dem Register mit dieser Nummer. Jede Anweisung enthält zwei Felder: einen Opcode (der die auszuführende Operation angibt) und das Adressfeld (das angibt, wo sich die Daten befinden, an denen die Operation ausgeführt werden soll). Erhöhen des Programmzählers (so dass er die Mailboxnummer der nächsten Anweisung enthält) Dekodieren der Anweisung. Entsprechend dem Befehl, auf die das neue angetragene Register springen (?), wenn die Operation von diesem Daten benötigt, z. B. 'Daten aus Postfach 42 abrufen' Daten abrufen (vom Eingang, Akku oder Register mit der in Schritt 4 ermittelten Adresse) Führen Sie die Anweisung basierend auf dem angegebenen Opcode aus Ergebnis verzweigen oder speichern (in der Ausgabe, im Akkumulator oder im Register mit der in Schritt 4 ermittelten Adresse) Kehren Sie zum Programmzähler zurück, um den Zyklus zu wiederholen oder anzuhalten.

Befehle

Während das LMC die tatsächliche Funktionsweise von Binär-Prozessoren widerspiegelt, wurde die Einfachheit von Dezimal-Zahlen gewählt, um die Komplexität für Schüler zu minimieren, die möglicherweise nicht mit der Arbeit im Binär/Hexadezimal vertraut sind.

Anleitung

Einige LMC-Simulatoren werden direkt mit dreistelligen numerischen Anweisungen programmiert, andere verwenden mnemonische Codes und Beschriftungen aus drei Buchstaben. In beiden Fällen ist der Befehlssatz bewusst sehr begrenzt (typischerweise etwa zehn Anweisungen), um das Verständnis zu vereinfachen. Wenn die LMC mnemonische Codes und Beschriftungen verwendet, werden diese beim Zusammenstellen des Programms in dreistellige numerische Anweisungen umgewandelt.

Die folgende Tabelle zeigt einen typischen numerischen Befehlssatz und die entsprechenden mnemonischen Codes.

+ Instructions Numeric code Mnemonic code Instruction Description 1xx ADD ADD Addiert den im Register xx gespeicherten Wert zu dem Wert, der sich derzeit im Akkumulator (Rechner) befindet. Hinweis: Der Inhalt des Registers wird nicht geändert und die Aktionen des Akkumulators (Rechners) ist nicht für Additionsanweisungen definiert, die Summen mit mehr als 3 Ziffern als Ergebnis hat

. Ähnlich wie bei SUBTRACT kann man bei Überlauf ein negatives Flag setzen. 2xx SUB SUBTRACTSubtrahiert den im Register xx gespeicherten Wert von dem Wert, der sich derzeit im Akkumulator (Rechner) befindet.

Hinweis: Der Inhalt des Registers wird nicht geändert und die Aktionen des Akkumulators sind nicht für Subtraktionsanweisungen definiert, die zu negativen Ergebnissen führen.

Es wird jedoch ein negatives Flag gesetzt, sodass '''7xx (BRZ)'' und „8xx (BRP)“ ordnungsgemäß verwendet werden kann 3xx STA STORE Speichert den Inhalt des Akkus im Register xx (destruktiv). Hinweis: Der Inhalt des Akkus (Rechner) wird nicht verändert (nicht destruktiv), aber der Inhalt des Registers wird ersetzt, unabhängig davon, was sich darin befand (destruktiv). 5xx LDA LOAD Lädt den Wert aus Registers xx (nicht destruktiv) und trägt ihn in den Akku ein (destruktiv). 6xx BRA BRANCH (Unbedingt) Setzt den Programmzähler auf die angegebene Adresse (Wert xx). Das heißt, der Wert im Register xx ist die nächste ausgeführte Anweisung. 7xx BRZ BRANCH IF ZERO (Bedingt) Wenn der Akku (Rechner) den Wert 000 enthält, setzt der Befehl den Programmzähler auf den Wert xx. Ansonsten tut er nichts. Ob das Negativ-Flag berücksichtigt wird, ist nicht definiert. Wenn ein SUBTRACT den Akku unterschreitet, wird dieses Flag gesetzt, woraufhin der Akku undefiniert ist, möglicherweise Null, was dazu führt, dass das Verhalten von BRZ bei Unterlauf undefiniert ist. Das vorgeschlagene Verhalten wäre eine Verzweigung, wenn der Akku Null ist und das Negativ-Flag nicht gesetzt ist. Hinweis: Da das Programm im Speicher gespeichert ist, haben alle Daten und Programmanweisungen das gleiche Adress-/Ortsformat. 8xx BRP BRANCH IF POSITIVE (Bedingt) Wenn der Akku (Rechner) 0 oder positiv ist, setzt es den Programmzähler auf den Wert xx. Ansonsten tun er nichts. Da LMC-Speicherzellen nur Werte zwischen 0 und 999 speichern können, hängt dieser Befehl ausschließlich vom negativen Flag ab, das durch einen Unterlauf bei SUBTRACT und möglicherweise von einem Überlauf bei ADD (undefiniert) gesetzt wird.

Hinweis: Da das Programm im Speicher gespeichert ist, haben alle Daten und Programmanweisungen das gleiche Adress-/Ortsformat. 901 INP INPUT Gehen Sie zum Posteingang, holen Sie den Wert vom Benutzer ab und geben Sie ihn in den Akku (Rechner) ein. Hinweis: Dadurch wird der Wert im Akkumulator überschrieben (destruktiv). 902 OUT OUTPUT Kopiert den Wert aus dem Akku (Rechner) in die OUTBOX (Ausgang). Hinweis: Der Inhalt des Akkus wird nicht verändert (zerstörungsfrei). 000 HLT/COB HALT/COFFEE BREAK Stopt / Hört auf zu arbeiten DAT DATA Dies ist eine Assembler-Anweisung, die den Wert einfach in das nächste verfügbare Register lädt. DAT kann auch in Verbindung mit Labels zum Deklarieren von Variablen verwendet werden. Beispielsweise speichert DAT 984 den Wert 984 in ein Register an der Adresse der DAT-Anweisung.

Beispiele

Verwendung numerischer Anweisungscodes Dieses Programm (Anweisung „901“ bis Anweisung „000“) ist nur mit numerischen Codes geschrieben. Das Programm nimmt zwei Zahlen als Eingabe und gibt die Differenz aus. Beachten Sie, dass die Ausführung bei Mailbox 00 beginnt und bei Mailbox 07 endet. Die Nachteile der Programmierung des LMC mit numerischen Befehlscodes werden im Folgenden erläutert.

Mailbox Numeric code Operation Comments 00 901 Accumulator = Inbox Gibt die erste Zahl ein und gibt sie in den Rechner (löscht alles, was dort war). 01 308 Mailbox 08 = Accumulator Speichert den aktuellen Wert des Rechners (zur Vorbereitung auf den nächsten Schritt ...) 02 901 Accumulator = Inbox INPUT the second number, enter into calculator (erasing whatever was there) 03 309 Mailbox 09 = Accumulator Gibt die zweite Zahl ein und übergibt sie in den Rechner (löschen Sie alles, was dort war) 04 508 Accumulator = Mailbox 08 (Jetzt werden beide INPUT-Werte in die Register 08 und 09 gespeichert...) Lädt den ersten Wert in den Rechner

(löscht alles, was dort war) 05 209 Accumulator = Accumulator - Mailbox 09 Subtrahiert die zweite Zahl vom aktuellen Wert des Rechners (der gerade auf die erste Zahl eingestellt ist) 06 902 Outbox = Accumulator Gibt das Ergebnis des Rechners an den Ausgang 07 000 Halt Hält die Maschine an

Verwendung von Mnemonikcodes und Beschriftungen

Assemblersprache ist eine Low-Level-Programmiersprache, die Mnemonikcodes und Beschriftungen anstelle numerischer Befehlscodes verwendet. Obwohl die LMC nur einen begrenzten Satz an Mnemonikcodes verwendet, wird die Bequemlichkeit der Verwendung eines Mnemonikcodes für jede Anweisung durch die unten gezeigte Assemblersprache desselben Programms deutlich – der Programmierer muss sich nicht länger einen Satz numerische Codes merken, sondern kann jetzt mit einer Reihe einprägsamerer mnemonischer Codes arbeiten. Wenn es sich bei der Mnemonik um eine Anweisung handelt, die eine Speicheradresse beinhaltet („entweder eine Verzweigungsanweisung oder das Laden/Speichern von Daten“), wird eine Bezeichnung zur Benennung der Speicheradresse verwendet.

INP STA FIRST INP STA SECOND LDA FIRST SUB SECOND OUT HLT FIRST DAT SECOND DAT

Labels

Ohne Labels muss der Programmierer die Registeradresse („Speicher“) manuell berechnen. Wenn im numerischen Codebeispiel ein neuer Befehl vor dem letzten HLT-Befehl eingefügt werden müsste, würde dieser HLT-Befehl von Adresse 07 zu Adresse 08 verschoben (die Adressbeschriftung beginnt an der Adressposition 00). Angenommen, der Benutzer hat als erste Eingabe 600 eingegeben. Die Anweisung 308 würde bedeuten, dass dieser Wert an der Adressstelle 08 gespeichert wird und die Anweisung 000 (HLT) überschreibt. Da 600 „Verzweigung zur Postfachadresse 00“ bedeutet, würde das Programm nicht anhalten, sondern in einer Endlosschleife stecken bleiben.

Um dieses Problem zu umgehen, kombinieren die meisten Assemblersprachen („einschließlich LMC“) die mnemonischen Zeichen mit Labels. Eine Bezeichnung ist einfach ein Wort, das verwendet wird, um entweder eine Speicheradresse zu benennen, an der eine Anweisung oder Daten gespeichert sind, oder um in einer Anweisung auf diese Adresse zu verweisen.

Programmzusammenstellung:

Eine Beschriftung links neben einer Befehlsmnemonik wird in die Speicheradresse umgewandelt, an der der Befehl oder die Daten gespeichert sind. d. h. loopstart INP Eine Beschriftung rechts neben einer Befehlsmnemonik nimmt den Wert der oben genannten Speicheradresse an. d. h. BRA loopstart Eine mit einer DAT-Anweisung kombinierte Bezeichnung fungiert als Variable und bezeichnet die Speicheradresse, an der die Daten gespeichert sind. d. h. „ein DAT 1“ oder „Nummer 1 DAT“