|
|
| Zeile 31: |
Zeile 31: |
| 14: stp | | 14: stp |
| 21: 5 | | 21: 5 |
| 22: 3 | | 22: 7 |
| 23: 0 | | 23: 0 |
| |Speicherkonfiguration3=# x - y = ? erweitert | | |Speicherkonfiguration3=# x - y = ? erweitert |
| Zeile 150: |
Zeile 150: |
| |2=Tipp anzeigen|3=Tipp verstecken}} | | |2=Tipp anzeigen|3=Tipp verstecken}} |
|
| |
|
| <!--
| |
| {{Lösung versteckt | | {{Lösung versteckt |
| |1=„x - y = ? (Betrag und Vorzeichen der Differenz für beliebige x und y)” in Assembler | | |1=„x - y = ? (Betrag und Vorzeichen der Differenz für beliebige x und y)” in Assembler |
| Zeile 182: |
Zeile 181: |
| |3=Lösung in Assembler verstecken}} | | |3=Lösung in Assembler verstecken}} |
|
| |
|
|
| |
| {{Lösung versteckt
| |
| |1=„x - y = ? (Betrag und Vorzeichen der Differenz für beliebige x und y)” in Maschinensprache
| |
| <pre>
| |
|
| |
| </pre>
| |
| |2=Lösung in Maschinensprache anzeigen
| |
| |3=Lösung in Maschinensprache verstecken}}
| |
| -->
| |
|
| |
|
| {{Box | | {{Box |
| Zeile 201: |
Zeile 191: |
| Das Programm heißt „Kleiner Gauß”, weil der berühmte Mathematiker Carl Friedrich Gauß einer Anekdote nach in der Schule schon als kleiner Junge die Summe der natürlichen Zahlen von 1 bis 100 sehr schnell mithilfe einer Formel berechnete, die er selbst entdeckt hatte und die heute als „Gaußsche Summenformel” bekannt ist. | | Das Programm heißt „Kleiner Gauß”, weil der berühmte Mathematiker Carl Friedrich Gauß einer Anekdote nach in der Schule schon als kleiner Junge die Summe der natürlichen Zahlen von 1 bis 100 sehr schnell mithilfe einer Formel berechnete, die er selbst entdeckt hatte und die heute als „Gaußsche Summenformel” bekannt ist. |
| |3=Üben}} | | |3=Üben}} |
| | |
| | {{Lösung versteckt |
| | |1= Lösungsidee: n wird in einer Schleife mehrfach zu s addiert, dabei aber bei jedem Schleifendurchgang um 1 verringert. Da bei jedem Additionsdurchgang der Wert in n auf 0 heruntergezählt wird, wird n jedesmal zusätzlich in der Hilfsspeicherstelle h gerettet. Vor dem Zurückspielen dieses geretteten Wertes von h nach n wird er um 1 verringert. So wird also schrittweise erst n nach s geschoben, dann n-1, dann n-2 usw. bis 1. |
| | |2=Tipp anzeigen |
| | |3=Tipp verstecken}} |
| | |
| | {{Lösung versteckt |
| | |1=„Kleiner Gauß 1 + 2 + 3 + ... + n = ?” Lösung in Assembler |
| | <pre> |
| | start1: isz n ; n=0? |
| | jmp nnachsundh ; nein: Weiter mit n nach s und h verschieben |
| | jmp htest ; ja: weiter mit htest |
| | nnachsundh: dec n |
| | inc s |
| | inc h |
| | jmp start1 ; Schleifenende von Verschiebung n nach s und h |
| | htest: isz h ; h=0? |
| | jmp hminus1 ; nein: Dann weiter bei hminus1 |
| | stp ; ja: fertig |
| | hminus1: dec h ; h um 1 verringern |
| | start2: isz h ; h=0? Schleifenanfang Rückverschiebung von verringertem h nach n |
| | jmp hnachn ; nein: Dann Rückverschiebung verringertes h nach n durchführen |
| | jmp start1 ; ja: Rückverschiebung von verringertem h nach n fertig, daher mit verringertem n von vorne |
| | hnachn: inc n |
| | dec h |
| | jmp start2 ; Schleifenende von Rückverschiebung h nach n |
| | n: 4 |
| | s: 0 ; Summenvariable |
| | h: 0 ; Hilfsvariable |
| | </pre> |
| | |2=Lösung in Assembler anzeigen |
| | |3=Lösung in Assembler verstecken}} |
|
| |
|
|
| |
|
| Zeile 219: |
Zeile 241: |
| ; Nach dem Programmende steht | | ; Nach dem Programmende steht |
| : Speicherzelle 29 der ggT von x und y, im Beispiel also der Wert 3. | | : Speicherzelle 29 der ggT von x und y, im Beispiel also der Wert 3. |
| | ; Hinweis |
| | : Dieses Maschinenprogramm erfordert mehr als 25 Speicherzellen im Hauptspeicher. |
| |3=Üben}} | | |3=Üben}} |
|
| |
|
Programmieraufgaben Teil 2
Hier kommen ein paar weitere Programmieraufgaben, die schon etwas anspruchsvoller sind. Entsprechend länger und unübersichtlicher sind die Maschinenprogramme. Daher macht es Sinn, erst ein Assemblerprogramm zu schreiben. Auch dieses kann man mit Stift und Streichhölzern erst mal „von Hand” auf dem Papier testen. Anschließend kann man es in die KHC-Maschinensprache übersetzen, um es z.B. im KHC-Emulator laufen zu lassen.
Programm testen im KHC-Emulator
# Alles auf 0
# Ist x < y ?
1: isz 21
2: jmp 4
3: jmp 7
4: isz 22
5: jmp 10
6: jmp 14
7: isz 22
8: jmp 13
9: jmp 14
10: dec 21
11: dec 22
12: jmp 1
13: inc 23
14: stp
21: 5
22: 7
23: 0
# x - y = ? erweitert
1: isz 23
2: jmp 4
3: jmp 7
4: isz 24
5: jmp 10
6: jmp 20
7: isz 24
8: jmp 13
9: jmp 20
10: dec 23
11: dec 24
12: jmp 1
13: isz 24
14: jmp 16
15: jmp 19
16: inc 23
17: dec 24
18: jmp 13
19: inc 24
20: stp
23: 3
24: 5
# Kleiner Gauß
1: isz 23
2: jmp 4
3: jmp 8
4: dec 23
5: inc 24
6: inc 25
7: jmp 1
8: isz 25
9: jmp 11
10: stp
11: dec 25
12: isz 25
13: jmp 15
14: jmp 1
15: inc 23
16: dec 25
17: jmp 12
18: 0
19: 0
20: 0
21: 0
22: 0
23: 4
24: 0
25: 0
# x * y = ?
1: isz 23
2: jmp 4
3: stp
4: isz 24
5: jmp 7
6: jmp 11
7: dec 24
8: inc 25
9: inc 22
10: jmp 4
11: isz 22
12: jmp 14
13: jmp 17
14: dec 22
15: inc 24
16: jmp 11
17: dec 23
18: jmp 1
19: 0
20: 0
21: 0
22: 0
23: 2
24: 3
25: 0
Auch hier gilt wieder für alle Übungsaufgaben:
- Alle Zellen des Hauptspeichers enthalten solange standardmäßig den Wert 0, bis etwas anderes per Tastatureingabe oder durch das Laden einer Speicherkonfiguration hineingeschrieben wird.
- Nach dem Programmende darf der Datenwert, der dann in einer Speicherzelle steht, von dem ursprünglichen Wert abweichen, der vor der Programmausführung in der Zelle stand.
5. Aufgabe „Ist x < y ?”
Entscheide, ob der Wert der Variablen x kleiner ist als der Wert der Variablen y.
- Vor dem Programmstart steht
- in Speicherzelle 21 ein beliebiger Wert x, z.B. der Wert 5, und
in Speicherzelle 22 ein beliebiger Wert y, z.B. der Wert 7.
- Nach dem Programmende steht
- in Speicherzelle 23 der Wert 1, wenn der ursprüngliche Wert von x kleiner als der ursprüngliche Wert von y war,
andernfalls steht in Speicherzelle 23 weiterhin der Initialisierungswert 0.
Hier kann man sich am Grundaufbau des Programms aus der 4. Aufgabe „Ist x = y ?” und an den entsprechenden Tipps orientieren.
6. Aufgabe „x - y = ? (Betrag und Vorzeichen der Differenz für beliebige x und y)”
Berechne die Differenz zweier beliebiger natürlicher Zahlen x und y. Im Gegensatz zu Aufgabe 2 wird jetzt nicht mehr zwingend vorausgesetzt, dass y kleiner oder gleich x sein muss. Das bedeutet, dass das Ergebnis nun auch negativ werden kann. Da im KHC negative Zahlen als Grunddatentypen nicht zugelassen sind, wird das Ergebnis in zwei Speicherzellen ausgegeben: die eine enthält den Betrag der Differenz und die andere das Vorzeichen des Ergebnisses, wobei der Wert 1 für ein negatives Ergebnis steht, der Wert 0 für ein nicht-negatives Ergebnis.
- Vor dem Programmstart steht
- in Speicherzelle 23 ein beliebiger Wert x, z.B. der Wert 3, und
in Speicherzelle 24 ein beliebiger Wert y, z.B. der Wert 5.
- Nach dem Programmende steht
- in Speicherzelle 23 der Betrag der Differenz x - y, im Beispiel also der Wert 2,
in Speicherzelle 24 der Wert 1, wenn das Ergebnis negativ ist und der Wert 0, wenn dies nicht der Fall ist.
Da im vorliegenden Beispiel das Ergebnis 3 - 5 = -2, also negativ ist, steht in diesem Fall
in Speicherzelle 23 der Betrag 2 und
in Speicherzelle 23 der Wert 1 für das negative Vorzeichen
Auch hier ist es sinnvoll, wie in den Programmen „Ist x = y ?” und „Ist x < y ?” eine entsprechende Fallunterscheidung durchzuführen.
„x - y = ? (Betrag und Vorzeichen der Differenz für beliebige x und y)” in Assembler
start: isz x ; Ist x=0 ?
jmp xistungleich0 ; nein: dann y überprüfen ab Marke xistungleich0
jmp xistgleich0 ; ja: dann y überprüfen ab Marke xistgleich0
xistungleich0: isz y ; Hier ist x!=0. Ist zusätzlich y=0?
jmp xundyungleich0 ; nein, dann ist x!=0 und y!=0, also ab Marke xundyungleich0
; beide verringern und dann Schleife wiederholen
jmp fertig ; ja: dann ist x!=0 und y=0, also fertig
xistgleich0: isz y ; Hier ist x=0. Ist zusätzlich y=0?
jmp ynachx ; nein: dann ist x=0 und y!=0, also y nach x kopieren und dann y=1 setzen
jmp fertig ; ja: dann ist x=0 und y=0, also fertig
xundyungleich0: dec x ; Hier ist x!=0 und y!=0. Daher werden x und y verringert
; und dann die Schleife wiederholt
dec y
jmp start ; zurück zum Start ganz nach oben
ynachx: isz y ; Ist y=0 ? Schleifenanfang des Kopiervorgangs y nach x
jmp yrunterxrauf ; nein: dann nächster Schritt, um y nach x kopieren
jmp yauf1 ; ja: Hier muss noch das negative Vorzeichen in y angezeigt werden
yrunterxrauf: inc x
dec y
jmp ynachx ; Schleifenende des Kopiervorgangs y nach x
yauf1: inc y ; y um 1 erhöhen (negatives Vorzeichen)
fertig: stp ; fertig
x: 5
y: 3
7. Aufgabe „Kleiner Gauß 1 + 2 + 3 + ... + n = ?”
Berechne die Summe der natürlichen Zahlen von 1 bis n, also 1+2+3+...+n.
- Vor dem Programmstart steht
- in Speicherzelle 23 ein beliebiger Wert n, z.B. der Wert 4.
- Nach dem Programmende steht
- in Speicherzelle 24 die Summe der natürlichen Zahlen von 1 bis 4, im Beispiel also der Wert 1+2+3+4 = 10.
Das Programm heißt „Kleiner Gauß”, weil der berühmte Mathematiker Carl Friedrich Gauß einer Anekdote nach in der Schule schon als kleiner Junge die Summe der natürlichen Zahlen von 1 bis 100 sehr schnell mithilfe einer Formel berechnete, die er selbst entdeckt hatte und die heute als „Gaußsche Summenformel” bekannt ist.
Lösungsidee: n wird in einer Schleife mehrfach zu s addiert, dabei aber bei jedem Schleifendurchgang um 1 verringert. Da bei jedem Additionsdurchgang der Wert in n auf 0 heruntergezählt wird, wird n jedesmal zusätzlich in der Hilfsspeicherstelle h gerettet. Vor dem Zurückspielen dieses geretteten Wertes von h nach n wird er um 1 verringert. So wird also schrittweise erst n nach s geschoben, dann n-1, dann n-2 usw. bis 1.
„Kleiner Gauß 1 + 2 + 3 + ... + n = ?” Lösung in Assembler
start1: isz n ; n=0?
jmp nnachsundh ; nein: Weiter mit n nach s und h verschieben
jmp htest ; ja: weiter mit htest
nnachsundh: dec n
inc s
inc h
jmp start1 ; Schleifenende von Verschiebung n nach s und h
htest: isz h ; h=0?
jmp hminus1 ; nein: Dann weiter bei hminus1
stp ; ja: fertig
hminus1: dec h ; h um 1 verringern
start2: isz h ; h=0? Schleifenanfang Rückverschiebung von verringertem h nach n
jmp hnachn ; nein: Dann Rückverschiebung verringertes h nach n durchführen
jmp start1 ; ja: Rückverschiebung von verringertem h nach n fertig, daher mit verringertem n von vorne
hnachn: inc n
dec h
jmp start2 ; Schleifenende von Rückverschiebung h nach n
n: 4
s: 0 ; Summenvariable
h: 0 ; Hilfsvariable
8. Aufgabe „Produkt x * y = ?”
Berechne das Produkt zweier Zahlen x und y.
- Vor dem Programmstart steht
- in Speicherzelle 23 ein beliebiger Wert x, z.B. der Wert 2, und
in Speicherzelle 24 ein beliebiger Wert y, z.B. der Wert 3.
- Nach dem Programmende steht
- in Speicherzelle 25 das Produkt x * y, im Beispiel also der Wert 2*3 = 6.
9. Aufgabe „Größter gemeinsamer Teiler ggT von x und y = ?”
Berechne den größten gemeinsamen Teiler zweier natürlicher Zahlen x und y, also den ggT von x und y.
- Vor dem Programmstart steht
- in Speicherzelle 27 eine beliebige natürliche Zahl x, z.B. der Wert 9 und
in Speicherzelle 28 eine beliebige natürliche Zahl y, z.B. der Wert 6.
- Nach dem Programmende steht
- Speicherzelle 29 der ggT von x und y, im Beispiel also der Wert 3.
- Hinweis
- Dieses Maschinenprogramm erfordert mehr als 25 Speicherzellen im Hauptspeicher.
Der ggT zweier natürlicher Zahlen x und y kann mit dem so genannten „Euklidischen Algorithmus“ berechnet werden:
„Euklid berechnete den größten gemeinsamen Teiler, indem er nach einem gemeinsamen „Maß“ für die Längen zweier Linien suchte. Dazu zog er wiederholt die kleinere der beiden Längen von der größeren ab. Dabei nutzt er aus, dass sich der größte gemeinsame Teiler zweier Zahlen (oder Längen) nicht ändert, wenn man die kleinere von der größeren abzieht.“ (siehe Wikipedia:
https://de.wikipedia.org/wiki/Euklidischer_Algorithmus)
start: isz x ; Ist x=0 ?
jmp xistungleich0 ; nein, dann y überprüfen ab Marke xistungleich0
jmp xistgleich0 ; ja, dann y überprüfen ab Marke xistgleich0
xistungleich0: isz y ; Hier ist x!=0. Ist zusätzlich y=0?
jmp xundyungleich0 ; nein, dann ist x!=0 und y!=0, also ab Marke xundyungleich0
; beide verringern und dann Schleife wiederholen
jmp xgroesser y ; ja, dann ist x!=0 und y=0, also weiter bei Marke xgroessery
xistgleich0: isz y ; Hier ist x=0. Ist zusätzlich y=0?
jmp ygroesserx ; nein, dann ist x=0 und y!=0, also weiter bei Marke ygroesserx
jmp xundygleich0 ; ja, dann ist x=0 und y=0, also weiter bei Marke xundygleich0 und fertig
xundyungleich0: dec x ; Hier ist x!=0 und y!=0. Daher werden x und y verringert und dann
; die Schleife wiederholt
dec y
inc z
jmp start ; Schleifenende: Zurück zum Anfang in Marke start
xundygleich0: stp ; fertig
xgroessery: isz z ; Schleife, um z nach y zu verschieben
jmp znachy
jmp start ; wenn z ganz nach y verschoben, dann das Ganze von vorn
znachy: inc y
dec z
jmp xgroessery
ygroesserx: isz z ; Schleife, um z nach x zu verschieben
jmp znachx
jmp start ; wenn z ganz nach x verschoben, dann das Ganze von vorn
znachx: inc x
dec z
jmp ygroesserx
x: 9 ; Beispielwert für x
y: 6 ; Beispielwert für y
z: 0 ; Vorgabewert für z