Registermaschine (Division)

dolmen

Newbie
Registriert
Juni 2020
Beiträge
6
Ich versuche seit einigen Tagen an einer Registermaschine (mit Harvard-Technologie) eine Division durchführen zu lassen. Es funktioniert aber überhaupt nicht. Hier der entsprechende Befehlssatz:

LDA (Lädt den Akku mit dem Wert der Speicherstelle n)
LDK (Lädt den Akku mit einer bestimmten Zahl)
STA (Überträgt den Akku-Inhalt an die Speicherstelle n)
ADD (Erhöht den Akku-Inhalt um den Inhalt der Speicherstelle n)
SUB (Erniedrigt den Akku-Inhalt um den Inhalt der Speicherstelle n)
JMP (Sprungbefehl an eine bestimmte Speicherstelle (Schleife))
JEZ (Sprungbefehl nur wenn der Akku den Wert 0 hat)
JNE (Sprungbefehl nur wenn der Akku nicht den Wert 0 hat)
JLZ (Sprungbefehl nur wenn der Akkuwert kleiner als 0 ist)
JLE (Sprungbefehl nur wenn der Akkuwert kleiner oder gleich 0 ist)
JGZ (Sprungbefehl nur wenn der Akkuwert größer als 0 ist)
JGE (Sprungbefehl nur wenn der Akkuwert größer oder gleich 0 ist)
INP (Eingabe eines Wertes in die Registermaschine)
OUT (Ausgabe eines Ergebnisses)
HLT (Programmausführung wird beendet)


Meine Idee bisher (die linke Zahl stellt den Programmspeicher dar, die rechte den Datenspeicher (außer bei LDK):

00 INP 01 (Eingabe des Dividenden an Speicherstelle 1)
01 INP 02 (Eingabe des Divisors an Speicherstelle 2)
02 LDA 01 (Lädt den Akku mit dem Dividenden)
03 SUB 02 (Erniedrigt den Akkuwert um den Wert des Divisors)
04 STA 04 (Überträgt den Akku-Inhalt an die Speicherstelle 4 im Datenspeicher)
05 LDA 05 (Lädt den Akku mit dem Wert von Speicherstelle 5 (also 0))
06 LDK 1 (Die Zahl 1 wird in den Akku geladen)
07 STA 05 (Überträgt den Akku-Inhalt (also jetzt 1) an die Speicherstelle 5 im Datenspeicher)
08 LDK 0 (Akku wird geleert)
09 ADD 05 (Erhöht den Akkuwert (also jetzt 0) um den Wert an Speicherstelle 5 (also um 1))
10 STA 03 (Überträgt den Akku-Inhalt (also jetzt 1) an die Speicherstelle 3 im Datenspeicher)
11 JMP 02 (Sprungbefehl zurück zu 03 SUB 02)
12 OUT
13 HLT

Wie gesagt, es funktioniert leider nicht. Erkennt jemand meine Fehler?
 
Was funktioniert nicht?
Wenn ich das richtig verstehe solltest du den Divisor so oft vom Dividenten abziehen bis du unter Null bist. die Anzahl wie oft du abgezogen hast ist dein Ergebnis. Die Zahl die vor dem letzten abziehen (bevor es unter Null ging) ist der Rest.
In deinem Code sehe ich keinen Bedingten Sprung JLE oder JGZ - sowas brauchst du hier und eben das Zählen wie oft du abziehst.
(ich dachte ich muss nach der Uni nie wieder Assembler sehen - aber irgendwie ists gar nicht so schlimm :-P. Aber kompliziertere Dinbge würde ich nicht anfassen)
 
Zuletzt bearbeitet:
05:
Wird von 06 wieder überschrieben.
Wie kannst Du sicher stellen, dass an der Speicherstelle 05 eine 0 steht?

04:
Wo wird der Dividend gesichert/geladen?

08:
Wie erhöht sich der Quotient?
Wo wird er gesichert/geladen?

11:
Ist ein unbedingter Sprung.

Nimm dir mal Beispielzahlen und schreib jeden Schritt auf (also Debugging auf dem Papier...):

Schritt | Befehlszeile | akku | (Speicherzelle) 01 02 03 04 05
=============================================
1 | 00 | 0 | x 0 0 0 0
2 | 01 | 0 | x y 0 0 0
...
 
@sandreas das ist pure Maschinensprache (Assembler). "Harvard-Technologie" ist der Hinweis für welche "Maschine". Solche Programme können direkt von dem jeweiligen Prozessor ausgeführt werden (die Befehle und Werte werden nur direkt in Nullen und Einsen übersetzt).

Sowas wird heutzutage hauptsächlich in der Lehre verwendet damit man mal gesehen hat wie Maschinen ticken. Ansonsten braucht man das fürs Reverse Engineering.
 
Hier ist jetzt mein neuester Versuch:

00 INP 01
01 INP 02
02 LDA 01
03 STA 04
04 LDA 04
05 SUB 02
06 STA 04
07 LDK 1
08 ADD 03
09 STA 03
10 LDA 02
11 ADD 03
12 JGZ 04
13 OUT 03
14 HLT

Ich bekomme den Akku einfach nicht rechtzeitig auf Null. Die Schleife bricht entweder zu früh oder überhaupt nicht ab (je nach Division). Woran könnte es liegen?
 
Bei 11 meintest du evtl. SUB 04?
Du solltest noch schauen, wie deine Maschine auf einen underflow reagiert.
 
Zurück
Oben