gReSim ist ein Rechnersimulator, der für die Lehre gedacht ist. Dargestellt wird ein Rechner mit Speicher, Register sowie Daten- und Adressbus. Der Rechner arbeitet in 5 Phasen - Einlesen, Dekodieren, Ausfuehren, Schreiben, PC setzen. Programme können komplett, befehlsweise aber auch phasenweise abgearbeitet werden und so die Veränderungen im Rechner jederzeit dargestellt werden.
gReSim ist in ANSI C mit einer GTK+-2.0-Oberfläche implementiert und somit sowohl unter Linux als auch unter Windows lauffähig.
gReSim darf ohne jede Einschränkung für jeden Zweck genutzt werden. Kommerzielle Nutzung ist ausdrücklich erlaubt. Modifikationen sind nur mit Zustimmung des Autors gestattet.
Download
gReSim_setup.exe (Windows-Setup inkl. GTK-Runtime, ~ 3 MB)
Unter Linux wird GTK+-2.0 benötigt.
gReSim32.bin (Linux, compiliert auf Knoppix v5.1.1 32-bit)
gReSim.bin (Linux, compiliert auf openSuse 10.3 64-bit)
gReSim_Assembler32.bin (Linux, compiliert auf Knoppix v5.1.1 32-bit)
gReSim_Assembler.bin (Linux, compiliert auf openSuse 10.3 64-bit)
16 Bit Datenbus | ||
16 Bit Adressbus | ||
8 Register | Reg 0 | |
Reg 1 | ||
Reg 2 | ||
Reg 3 | ||
Reg 4 = PC Befehlszähler | ||
Reg 5 = SP Stackpointer | ||
Reg 6 = BP Basepointer | ||
Reg 7 = SR Statusregister | ZF Zero Flag | |
NF Negative Flag | ||
OF Overflow Flag | ||
DF Division by Zero Flag | ||
3 Zusatz-Register für die Anzeige | AB Adressregister | Anzeige Adressbus |
DB Datenregister | Anzeige Datenbus | |
IR Befehlsregister | Anzeige aktuelles Befehlswort unterhalb des IR wird der dekodierte Befehl angezeigt; weiterhin wird durch Pfeile angegeben, ob fuer diesen; Befehl Teile des Befehlswortes auf Register verweisen |
|
65536 Speicherworte | 1 Speicherwort = 16 Bit | |
128 kByte Arbeitsspeicher | ||
Speicherworte ab 64512 für I/O reserviert | ||
SP, BP bei Initialisierung auf 64512 | ||
16 Bit Befehlswort | ||
für 0xxxx-Befehle | 6 Bit Befehl | |
1 Bit frei | ||
3 Bit Reg_Operand1 | ||
3 Bit Reg_Operand2 | ||
3 Bit Reg_Ergebnis | ||
für 1xxxx-Befehle | 6 Bit Befehl | |
1 Bit 0 für direkte 1 für indirekte Adressierung | ||
6 Bit frei bei direkter Adressierung ansonsten enthalten die ersten 3 Bit ein Register | ||
3 Bit Register | ||
16 Bit Adresse |
000000 | HALT | |
000001 | MOVE | Reg_Op1 -> Reg_Erg |
000010 | PUSH | Reg_Op1 -> Adr in SP -1 |
000011 | POP | Adr in SP -> Reg_Erg |
000111 | NOOP | |
001000 | ADD | Reg_Op1 + Reg_Op2 -> Reg_Erg |
001001 | SUB | Reg_Op1 - Reg_Op2 -> Reg_Erg |
001010 | MULT | Reg_Op1 * Reg_Op2 -> Reg_Erg |
001011 | DIV | Reg_Op1 / Reg_Op2 -> Reg_Erg |
001100 | MOD | Reg_Op1 % Reg_Op2 -> Reg_Erg |
010000 | RSHIFT | Reg_Op1 >> Reg_Op2 -> Reg_Erg |
010001 | LSHIFT | Reg_Op1 << Reg_Op2 -> Reg_Erg |
011000 | AND | Reg_Op1 & Reg_Op2 -> Reg_Erg |
011001 | OR | Reg_Op1 | Reg_Op2 -> Reg_Erg |
011010 | NOT | ! Reg_Op1 -> Reg_Erg |
011011 | XOR | Reg_Op1 ^ Reg_Op2 -> Reg_Erg |
011100 | NAND | ! (Reg_Op1 & Reg_Op2) -> Reg_Erg |
011101 | NOR | ! (Reg_Op1 | Reg_Op2) -> Reg_Erg |
100000 | LOAD | Reg -> Adr |
100001 | STORE | Adr -> Reg |
110000 | JUMP | |
110001 | JZERO | wenn Zero-Flag gesetzt |
110010 | JNZERO | wenn Zero-Flag nicht gesetzt |
110011 | JNEG | wenn Negative-Flag gesetzt |
110100 | JNNEG | wenn Negative-Flag nicht gesetzt |
110101 | JOVER | wenn Overflow-Flag gesetzt |
110110 | JNOVER | wenn Overflow-Flag nicht gesetzt |
110111 | JDIV | wenn DivByZero-Flag gesetzt |
111000 | JNDIV | wenn DivByZero-Flag nicht gesetzt |
Ist für die 1xxxxx-Befehle indirekte Adressierung (Bit 7) gesetzt, so wird die notwendige Adresse aus einem Register gelesen.
Das Register wird mit den Bits 8, 9 und 10 angegeben.
0. Einlesen | DR und IR wird mit dem nächsten Befehl belegt. | |
Laden des AR mit PC+1 | ||
1. Dekodieren | Push: | SP--, Laden AR aus SP |
Pop: | Laden des AR aus SP | |
Load: | Laden des AR | |
2. Ausfuehren | Move/Push/Pop: | Laden des DR |
arith./log. Bef./Shift: | Berechnung durchführen - Erg nach DR Setzen der Flags Bei Div durch 0 bleibt DR unverändert. |
|
Load: | Laden des DR | |
Store: | Laden des DR Laden des AR |
|
Sprungbefehle: | Prüfen, ob Sprung ausgeführt wird Laden des DR |
|
3. Schreiben | Move/Push/Pop: | Schreiben aus DR in Ziel |
arith./log. Bef./Shift: | Schreiben aus DR in Ziel | |
Load/Store: | Schreiben aus DR in Ziel | |
4. PC setzen | Move/Push: | PC um 1 erhöhen |
Pop: | PC um 1 erhöhen, Setzen SP | |
arith./log. Bef./Shift: | PC um 1 erhöhen | |
Load/Store: | PC um 2 erhöhen | |
Sprungbefehle: | Falls Sprung PC aus AR laden, sonst PC um 2 erhöhen |
|
Allgemein | AR wird mit dem neuen Inhalt des PC belegt |
Dateien, die geladen werden koennen, muessen die Endung .mrs tragen.
Der Inhalt der Dateien muss aus Maschinenbefehlen bestehen.
Die Befehle sind als 16-bit Worte in hexadezimaler Schreibweise anzugeben.
Die Ausgabe erfolgt über das Speicherwort mit der Adresse 65535, die Eingabe über das Speicherwort mit der Adresse 65534. Übertragen werden jeweils die rechten acht Bit interpretiert nach dem ASCII-Code. Das 9.Bit dient als Flag.
Ausgabe:
Ist am Ende eines Befehls das 9.Bit des Speicherwortes 65535 nicht gesetzt, so werden die rechten acht Bit als ASCII-Zeichen ausgegeben. Nach der Ausgabe wird das 9.Bit auf eins gesetzt.
Eingabe:
Wird in der Phase "Ausfuehren" lesend auf das Speicherwort 65534 zugegriffen und wurde das 9.Bit dieses Speicherwortes seit dem letzten Lesezugriff auf dieses Speicherwort auf eins gesetzt, so wird vom Nutzer das Drücken einer Taste gefordert. Der ASCII-Code des gedrückten Zeichens wird dann auf den Datenbus gelegt.
Ist am Ende eines Befehls das neunte Bit des Speicherwortes 65534 auf eins gesetzt, so wird dieses Bit auf null gesetzt. Mit dem Auslesen des Speicherwortes und dem Setzen des 9.Bits dieses Speicherwortes wurde ein Zeichen aus dem Tastaturpuffer gelesen.
Übersetzt erweiterten Assembler-Quellcode in Maschinensprache für den Simulator gReSim. Der Assembler kann Dateien mit der Endung "*.ers" verarbeiten und erzeugt eine Datei gleichen Namens mit der Endung "*.mrs".
In der Assemblersprache ist das Setzen von Marken erlaubt. Eine Marke besteht aus dem Doppelpunkt und einem Bezeichner. Der Bezeichner beginnt mit einem Kleinbuchstaben und darf eine maximale Länge von 20 Zeichen besitzen.
Folgende Befehle werden akzeptiert:
HALT | |
NOOP | |
RETURN | |
PUSH | register |
POP | register |
MOVE | register register |
NOT | register register |
ADD | register register register |
SUB | register register register |
MULT | register register register |
DIV | register register register |
MOD | register register register |
RSHIFT | register register register |
LSHIFT | register register register |
AND | register register register |
OR | register register register |
XOR | register register register |
NAND | register register register |
NOR | register register register |
LOAD | register marke |
STORE | register marke |
JUMP | marke |
JZERO | marke |
JNZERO | marke |
JNEG | marke |
JNNEG | marke |
JOVER | marke |
JNOVER | marke |
JDIV | marke |
JNDIV | marke |
PREPARE | marke |
CALL | marke |
Register werden als Dezimalzahl, Marken durch ihre Bezeichner angegeben.
Aufruf:
PREPARE radr | <-- RA und BP werden auf den Stack gelegt |
PUSH ... | <-- Parameter auf den Stack legen* |
CALL uprg | |
:radr | |
NOOP | <-- notwendig |
Unterprogramm:
:uprg | |
... | <-- Befehle des Unterprogramms |
RETURN |
Die Rückgabe erfolgt über die Register oder den Speicher. Hierfür ist der Programmierer selbst verantwortlich.
*Eine Parameterübergabe über die Register ist ebenfalls möglich. Der Assembler verändert lediglich das Statusregister.
Zwischen den Befehlen und den Operanden ist jeweils nur ein Leerzeichen erlaubt.
Leerzeilen oder Kommentare sind nicht erlaubt.
Powered by CMSimple| Template: ge-webdesign.de| Impressum| Login