An ASSEMBLER - Götter

Hallo,

unser Prof hat eine Aufgabe zur Assembler-Programmierung für Harvard-Rechner gestellt, mit der ich nichts anfangen kann

„ein Mikroprozessor habe einen 16-bit-Akkumulator (ACC) und greife auf einen Programm- und Datenspeicher von 16-bit Worten zu. Das Statusregister besteht aus den beiden Bits C (Carry) und Z (Zero), die bei Additionen und Subtraktionen gesetzt werden. Er habe den Befehlssatz

LAC n Lade ACC aus dem Datenspeicher, setze Z
SAC n Speichere ACC in den Datenspeicher
ADD n Addiere Datenspeicherinhalt zu ACC
SUB n Subtrahiere Datenspeicherinhalt von ACC
ADDC n Addiere Datenspeicherinhalt zu ACC mit Übertrag
SUBC n Subtrahiere Datenspeicherinhalt von ACC mit Übertrag
B n Absoluter Sprung
BC n Sprung, falls C = 1
BNC n Sprung, falls C = 0
BZ n Sprung, falls Z = 1
BNZ n Sprung, falls Z = 0

Wobei n eine Adresse im Bereich 0,…, 4095 darstellt. Schreiben Sie ein Assemblerprogramm für diesen Prozessor, welches den ggT von zwei 32-bit-Zahlen an den Speicherstellen 256/257 und 258/259 berechnet und das Ergebnis in den Speicherstellen 260/261 hinterlässt.

ggT(a, b) = a, für a=b
ggT(a, b) = ggT(a-b, b), für a>b
ggT(a, b) = ggT(b, a), für a

Hallo Christoph,

1.) ich bin kein Assemblerprogrammierer … :wink: (mehr)
Vor Jahren habe ich mal auf 8-Bit Rechnern Assembler programmiert. Die Befehle die Du schreibst scheinen da entlehnt zu sein, sehen sehr ähnlich aus. Deshalb denke ich, daß ich damit ein Programm schreiben könnte, … wenn ich die Aufgabe verstehen würde.

Schreiben Sie ein Assemblerprogramm für diesen Prozessor,
welches den ggT

??? was heißt ggT ?

von zwei 32-bit-Zahlen an den Speicherstellen
256/257 und 258/259 berechnet und das Ergebnis in den
Speicherstellen 260/261 hinterlässt.

das ist wieder klar. Die gewünschtre Rechenoperation selbst verstehe ich nicht.

ggT(a, b) = a, für a=b
ggT(a, b) = ggT(a-b, b), für a>b
ggT(a, b) = ggT(b, a), für a b dann c=??? a-b? was verstehe ich unter ,b?

cu Rainer

Hallo,

mal den Anfang einer Lösung, soweit ich die Aufgabe verstanden habe. :wink:

1 LAC 256 Lade Accu mit dem Inhalt von Adresse 256
2 SUBC 258 Subtrahiere davon den Inhalt von Adresse 258
3 BC n Wenn das Carry-flag gesetzt ist, war das ergebnis Negativ, ‚b‘ ist größer als ‚a‘
4 LAC 258 Hi von ‚b‘ in den Accu laden
5 SUBC 256 Hi von ‚a‘ subtrahieren
6 BC 18 Wenn Carry gesetzt ist, ist ‚a‘ > ‚b‘
Wenn das Programm diese Zeile erreicht, weiter prüfen.
7 LAC 257 Lo von ‚a‘ in den Accu laden
8 SUBC 259 Lo von ‚b‘ subtrahieren
9 BC n ‚b‘ > ‚a‘
10 LAC 259
11 SUBC 257
12 BC 18 ‚a‘ > ‚b‘
Jetzt steht fest, a = b
13 LAC 256 Hi laden
14 SAC 260 und schreiben
15 LAC 257 Lo laden
16 SAC 261 und schreiben
17 B n Exit. An das Ende Springen, Programm verlassen. Für a=b Aufgabe erfüllt
Hier einspringen, wenn a > b
18 ???

Klar so weit?
(Schade, daß meine ‚Tabs‘ nicht übernommen werden. So sieht es unübersichtlich aus.)

cu Rainer

Schreiben Sie ein Assemblerprogramm für diesen Prozessor,
welches den ggT

??? was heißt ggT ?

ggT heißt im Normalfall „größter gemeinsamer Teiler“

Gerhard

Hallo Gerhard,

ggT heißt im Normalfall „größter gemeinsamer Teiler“

danke, das war mir so nicht geläufig. Das habe ich wohl vergessen, daß ich das letzte mal Mathe hatte ist schon eine Weile her. :wink:

cu Rainer

Hallo Rainer,

vielen Dank für deine Lösung!

was sind „Lo“ und „Hi“ ? :wink:)

ein Kommilitone meint, das folgende Programm sei richtig. Kann man solche Programme irgenwie testen?

1: LAC 256 ;oberes Halbwort des ersten Argumentes laden
2: SUB 258 ;obere Halbworte subtrahieren
3: BZ 19 ;bei Null Sprung nach 19
4: BNC 12 ;kein Carry -> Sprung nach 12, sonst weiter

5: LAC 259 ;zweite Zahl größer als erste -> unteres Halbwort der größeren Zahl laden
6: SUB 257 ;unteres Halbwort der kleineren Zahl abziehen
7: SAC 259 ;Ergebnis speichern, größere Zahl überschreiben
8: LAC 258 ;oberes Halbwort der größeren Zahl laden
9: SUBC 256 ;oberes Halbwort der kleineren Zahl + Übertrag der vorherigen Subtraktion abziehen
10: SAC 258 ;Ergebnis speichern, größere Zahl überschreiben
11: B 1 ;Sprung nach 1, erneuter Durchlauf

12: LAC 257 ;erste zahl größer als zweite -> unteres Halbwort der größeren Zahl laden
13: SUB 259 ;unteres Halbwort der kleineren Zahl abziehen
14: SAC 257 ;Ergebnis speichern, größere Zahl überschreiben
15: LAC 256 ;oberes Halbwort der größeren Zahl laden
16: SUBC 258 ;oberes Halbwort der kleineren Zahl + Übertrag der vorherigen Subtraktion abziehen
17: SAC 256 ;Ergebnis speichern, größere Zahl überschreiben
18: B 1 ;Sprung nach 1, erneuter Durchlauf

19: LAC 257 ;obere Halbwörter sind gleich -> unteres Halbwort der ersten Zahl laden
20: SUB 259 ;unteres Halbwort der zweiten zahl abziehen
21: BZ 24 ;beide Zahlen sind gleich -> Sprung nach 24
22: BC 5 ;bei Carry -> Sprung nach 5
23: BNC 12 ;kein carry -> Sprung nach 12

24: LAC 256 ;beide Zahlen sind gleich, Algorithmus terminiert -> unteres Halbwort der ersten Zahl laden
25: SAC 260 ;und an die vorgesehene Speicherstelle schreiben
26: LAC 257 ;oberes Halbwort laden
27: SAC 261 ;und abspeichern
28: RET 0 ;Ende

Gruß, Christoph

Hallo Christoph,

was sind „Lo“ und „Hi“ ? :wink:)

das schreibst Du doch gerade…

1: LAC 256 ; oberes Halbwort des ersten Argumentes laden
2: SUB 258 ;obere Halbworte subtrahieren

ein Kommilitone meint, das folgende Programm sei richtig.

Ja, ich meine, der Anfang sieht richtig aus. Nur werden am Anfang nur die oberen Halbwörter (hi) geprüft. Ob der weitere Verlauf dann richtig ist, kann ich nicht genau sagen, weil ich den mathematischen Hintergrund immer noch nicht ganz verstanden habe. Ich sehe mir im Laufe des Tages das Programm noch genauer an, eventuell verstehe ich es ja dann. :wink:
Das Prinzip des Programms ist aber richtig.

Kann man solche Programme irgenwie testen?

Wenn man sich mit einer einfacheren Sprache (Basic?) einen Emulator zusammenbastelt kann man das. Das dürfte aber ein paar Stunden dauern, bis der zuverlässig funktioniert.

cu Rainer