WEBVTT

00:05.450 --> 00:07.110
So, schönen guten Tag.

00:08.650 --> 00:11.630
Herzlich willkommen zur nächsten Vorlesung Grundbegriffe der

00:11.630 --> 00:12.530
Informatik.

00:13.290 --> 00:16.790
Machen wir weiter mit dem Kapitel Wie ist grob ein Prozessor

00:16.790 --> 00:17.450
aufgebaut?

00:21.490 --> 00:24.570
Grundlage, naja, wir hatten schon...

00:24.570 --> 00:27.530
Also erstmal werden Sie sehen, wir haben dann in so einem Prozessor

00:27.530 --> 00:32.910
irgendwie mehrere potenzielle Erzeugerverbraucher, die ein Bit oder

00:32.910 --> 00:36.990
mehrere Bits liefern können oder verarbeiten können, miteinander

00:36.990 --> 00:37.490
verbunden.

00:37.670 --> 00:38.970
Das ist dann ein sogenannter Bus.

00:40.210 --> 00:43.290
Da können potenziell verschiedene Ihre Werte drauflegen, aber bitte zu

00:43.290 --> 00:44.810
jedem Zeitpunkt immer nur einer.

00:45.130 --> 00:46.250
Alles andere ist verboten.

00:48.090 --> 00:51.470
Und wenn da Verbraucher sind, dann können die die Werte, die da sind,

00:52.710 --> 00:53.070
lesen.

00:54.090 --> 00:57.650
Und da kann man auch mehrere Leitungen parallel haben, um dann drei

00:57.650 --> 01:02.470
oder 20 oder 24 Bits kreuz und quer durch die Gegend zu schieben.

01:03.090 --> 01:03.270
Gut.

01:06.150 --> 01:10.750
Und dann hat man also, insbesondere, werden Sie gleich sehen, solche

01:10.750 --> 01:17.550
einfachen Speicher, dann hier ist sowas für vier Bits hingemalt.

01:17.930 --> 01:22.010
Wir werden es dann für 20 und 24 Bits haben, aber nur noch schematisch

01:22.010 --> 01:22.710
als Kästchen.

01:23.370 --> 01:27.730
Da haben Sie also dann 20 oder 24 Einheiten, wo intern immer ein Bit

01:27.730 --> 01:28.930
gespeichert werden kann.

01:29.090 --> 01:30.710
Und es gibt zwei Steuersignale.

01:30.890 --> 01:33.670
Eins, um zu sagen, jetzt das, was gespeichert ist, möchten wir bitte

01:33.670 --> 01:35.910
auf dem Bus lesen können.

01:37.690 --> 01:43.350
Oder, und zwar exklusives oder nicht gleichzeitig, das, was gerade auf

01:43.350 --> 01:46.570
dem Datenbus oder auf dem Bus von irgendwoher kommt, soll jetzt in

01:46.570 --> 01:48.150
diesem Register gespeichert werden.

01:50.110 --> 01:53.650
Und das, was vorher gespeichert war, ist weg und der neue Wert ist

01:53.650 --> 01:55.970
drin und wird nicht vergessen.

01:58.130 --> 02:04.030
Und dann haben wir also, wo waren wir denn, hier so grob den Aufbau

02:04.030 --> 02:09.470
dieses idealisierten Prozessors, den wir uns hier angucken wollen, der

02:09.470 --> 02:14.070
auch in mindestens einer anderen Vorlesung aus der technischen

02:14.070 --> 02:15.890
Informatik wieder auftauchen wird.

02:17.050 --> 02:20.990
Ich erzähle Ihnen jetzt nicht alle Details, ich erzähle Ihnen noch

02:20.990 --> 02:27.970
nicht mal alle Maschinenbefehle, ist auch nicht wichtig, aber grob der

02:27.970 --> 02:28.490
Aufbau.

02:29.550 --> 02:35.830
So, und der ist halt so, wie er in praktisch allen, also ja, praktisch

02:35.830 --> 02:40.390
allen normalen, gängigen Prozessoren heutzutage anzutreffen ist.

02:41.050 --> 02:44.690
Da hat man so ganz grob eine Dreiteilung, nämlich erstens ein

02:44.690 --> 02:45.510
Steuerwerk.

02:47.790 --> 02:51.530
Da gibt es also erst mal da oben diesen Kasten, wo Steuerwerk

02:51.530 --> 02:56.430
drinsteht, was da genau passiert, sehen Sie dann in technischer

02:56.430 --> 02:56.710
Informatik.

02:57.610 --> 03:01.910
Und es gibt jedenfalls zwei Register, die heißen hier IR und IAR.

03:02.870 --> 03:07.690
IR steht für Instruktionsregister und da steht immer drin, der

03:07.690 --> 03:11.410
Maschinenbefehl, also die Codierung, eine Bitfolge für den

03:11.410 --> 03:13.570
Maschinenbefehl, der als nächstes auszuführen ist.

03:14.050 --> 03:15.810
Das ist im Instruktionsregister.

03:17.550 --> 03:22.550
IAR ist das Instruktionsadressregister, da steht eine Adresse drin,

03:23.370 --> 03:27.690
und zwar, wenn man irgendwann fertig ist mit einem Maschinenbefehl,

03:27.770 --> 03:28.890
steht da die Adresse drin.

03:30.470 --> 03:32.390
Wo kommt denn jetzt der nächste Befehl her?

03:33.330 --> 03:37.110
Also zu jedem Zeitpunkt, man hat nur einen im Prozessor drin

03:37.110 --> 03:38.850
sozusagen, alle anderen sind im Speicher.

03:39.530 --> 03:43.150
Und dann gibt es das Rechenwerk, das macht also aus Bitmustern andere

03:43.150 --> 03:47.110
Bitmustern, die irgendwie mit Addition oder was auch immer zu tun

03:47.110 --> 03:47.470
haben.

03:47.990 --> 03:53.190
Und es gibt einen Register, der heißt typischerweise Akkumulator, wo

03:53.190 --> 03:57.870
man halt so einen Wert zwischenspeichern kann, ohne ihn gleich in den

03:57.870 --> 03:59.010
Speicher schieben zu müssen.

03:59.770 --> 04:05.510
Und dann gibt es eben drittens den Teil, der sich mit, so grob gesagt,

04:05.670 --> 04:12.910
der Daten und der Programmspeicher und bei diesem Aufbau von Neumann

04:12.910 --> 04:14.950
-Architektur wird da nicht groß unterschieden.

04:15.070 --> 04:17.610
Da gibt es einen Speicher, da liegen sowohl die Daten drin, die man

04:17.610 --> 04:19.730
verarbeitet, als auch die Befehle, die ausgeführt werden.

04:21.070 --> 04:25.610
Und das meiste stellen wir uns jetzt mal der Einfachheit halber so

04:25.610 --> 04:27.570
vor, ist externer Speicher.

04:28.510 --> 04:31.550
Wenn Sie schon mal einen Rechner aufgeschraubt gesehen haben, da

04:31.550 --> 04:34.850
stecken dann halt immer so zwei oder vier, vielleicht auch nur ein, so

04:34.850 --> 04:40.210
ein kleiner Speicherregel in irgendeinem Slot mit 288 Anschlüssen oder

04:40.210 --> 04:40.510
was.

04:40.870 --> 04:44.830
Und es gibt halt so ein kleines bisschen eine Schnittstelle noch im

04:44.830 --> 04:49.770
Prozessor, um dann auf den Speicher zuzugreifen, von da was zu lesen,

04:49.930 --> 04:50.910
da was hinzuschreiben.

04:53.350 --> 04:55.890
Und diese ganzen Dinger, die müssen jetzt natürlich irgendwie

04:55.890 --> 04:59.070
miteinander verbunden werden, aus dem Speicher muss irgendwas ins

04:59.070 --> 05:03.290
Instruktionsregister kommen, mindestens vielleicht auch mal hier zum

05:03.290 --> 05:06.150
Rechenwerk, in den Akkumulator und dafür gibt es dann einen großen

05:06.150 --> 05:08.270
Bus, der alle...

05:11.960 --> 05:16.160
sowohl Daten als auch Adressen transportieren kann bei dem Prozessor

05:16.160 --> 05:16.480
hier.

05:17.140 --> 05:20.560
Die Werte, die da auf einmal aus dem Speicher kommen, sind, wollen wir

05:20.560 --> 05:22.360
annehmen, 24 Bit breit.

05:23.440 --> 05:29.360
Und dann hier so ein Bus, so eine dickere blaue Linie, stellen Sie

05:29.360 --> 05:32.440
sich bitte vor, das sind 24 Bit, die da ankommen oder weggehen.

05:33.500 --> 05:37.200
Und so die etwas dünneren Linien, die sind 20 Bit breit, das sind die

05:37.200 --> 05:37.640
Adressen.

05:37.740 --> 05:41.640
Also die Annahme ist hier bei der Architektur, man kann zwei hoch 20

05:41.640 --> 05:44.760
Speicherworte adressieren und jedes ist 24 Bit groß.

05:45.940 --> 05:49.120
So und da sehen Sie also da Instruktionsregister,

05:49.200 --> 05:53.980
Instruktionsadressregister, den Akkumulator, dann gibt es hier etwas

05:53.980 --> 05:57.680
genauer noch ein Register, das ist einfach bequem, sich vorzustellen,

05:57.960 --> 06:00.020
es gibt ein Register, da steht immer 1 drin.

06:00.220 --> 06:03.500
Das können Sie auch nicht schreiben, das können Sie nur lesen und so

06:03.500 --> 06:05.760
oft Sie es lesen, da kommt immer einfach die 1 raus.

06:06.560 --> 06:08.100
Ist manchmal ein nützlicher Wert.

06:09.960 --> 06:13.780
Dann tatsächlich in dem Rechenwerk ist die Vorstellung, man hat hier

06:13.780 --> 06:20.540
zwei Register, die heißen ja einfach X und Y, da sind die Werte drin,

06:20.840 --> 06:25.780
die verarbeitet werden sollen von der Einheit und dann kommt immer ein

06:25.780 --> 06:30.740
Ergebnis raus, Z, das landet auch erstmal wieder in einem Register und

06:30.740 --> 06:34.240
das sind alles, wie gesagt, 24 Bit Werte und deswegen hier dann auch

06:34.240 --> 06:36.320
alles verbunden mit diesem großen Bus.

06:36.740 --> 06:39.700
Und hier hinten für die Anbildung vom Hauptspeicher gibt es zwei

06:39.700 --> 06:44.380
Register, das eine ist das Speicheradressregister, da steht immer eine

06:44.380 --> 06:48.520
Adresse drin, nämlich die, für die man sich jetzt gerade interessiert

06:48.520 --> 06:52.080
im Hauptspeicher, wo man was schreiben oder lesen will und das

06:52.080 --> 06:56.960
Speicherdatenregister, beim Lesen steht dann nachhin reichen langer

06:56.960 --> 07:01.260
Zeit das Speicherwort drin, dessen Adresse man hier hatte, das man

07:01.260 --> 07:04.120
lesen wollte und wenn man was schreiben will, muss man halt vorher

07:04.120 --> 07:06.760
hier den Wert reintun, der dann in den Speicher transportiert wird.

07:08.660 --> 07:12.860
Also es gibt hier einen großen Bus, alle möglichen Register können da

07:12.860 --> 07:18.000
was lesen, was schreiben, aber bitte zu jedem Zeitpunkt maximal einer

07:18.000 --> 07:19.900
darf was schreiben, nicht verschiedene.

07:20.880 --> 07:24.200
Man muss bei der Architektur ein bisschen aufpassen, weil hier, also

07:24.200 --> 07:27.420
manche Busse, so ein Teil der Busse ist irgendwie schmäler, nur 20

07:27.420 --> 07:32.500
Bit, der Rest ist 24 Bit, da gibt es zwei Stellen, da muss man bei der

07:32.500 --> 07:33.700
Erklärung ein bisschen aufpassen.

07:37.120 --> 07:41.320
Und damit zum Beispiel immer höchstens ein Register seinen Wert auf

07:41.320 --> 07:45.500
dem Bus legt, gibt es da einen Haufen Steuersignale, zum Beispiel zu

07:45.500 --> 07:50.100
den ganzen Registern, wo dann immer maximal einer sagt, du legst jetzt

07:50.100 --> 07:54.300
deinen Wert auf den Bus drauf und die anderen sagen höchstens, du

07:54.300 --> 07:56.000
kannst jetzt den Wert lesen von dem Bus.

07:56.920 --> 08:02.280
Und es gibt auch so ein paar Leitungen, so Meldesignale zum Steuerwerk

08:02.280 --> 08:07.240
hin, da kriegt das Steuerwerk zum einen die Information aus dem

08:07.240 --> 08:11.180
Instruktionsregister, um welchen Befehl soll es denn eigentlich gehen.

08:12.000 --> 08:16.940
Also im Instruktionsregister so ein Befehl, die vorderen 4 oder in

08:16.940 --> 08:21.520
manchen Fällen 8 Bit sagen, was soll getan werden, der Rest ist was

08:21.520 --> 08:21.820
anderes.

08:23.200 --> 08:28.100
Und es gibt eine Meldeleitung vom Abkumulator, das höchstwertige Bit,

08:28.660 --> 08:31.580
das geht auch zum Steuerwerk.

08:32.320 --> 08:35.840
Und wir haben hier Repräsentation von Zahlen im Zweierkomplement, das

08:35.840 --> 08:38.680
heißt, das höchstwertige Bit sagt einfach, wenn es eine 1 ist, die

08:38.680 --> 08:42.120
Zahl ist negativ und wenn es eine 0 ist, die Zahl ist nicht negativ.

08:42.120 --> 08:43.700
0 oder positiv.

08:45.700 --> 08:48.040
So, also das ist grob der Aufbau.

08:49.920 --> 08:56.860
Und jetzt gucken wir uns dann so nach und nach an, was da passiert,

08:56.940 --> 08:58.960
wenn ein Maschinenbefehl ausgeführt wird.

08:59.500 --> 09:00.640
Wie wird das eigentlich gemacht?

09:02.180 --> 09:07.380
Also wie gesagt, dieses Ding hat von Neumann Architektur,

09:10.920 --> 09:14.840
also rein theoretisch ein Programm, das abgearbeitet wird, kann sich

09:14.840 --> 09:15.800
selbst verändern.

09:16.620 --> 09:18.800
Das will man in der Regel nicht haben.

09:20.220 --> 09:23.220
Heute die echten Prozessoren haben vielleicht so eine Mischung aus

09:23.220 --> 09:25.800
dieser von Neumann Architektur und der sogenannten Harvard

09:25.800 --> 09:30.160
Architektur, wo sie tatsächlich getrennte Speicherbereiche jedenfalls

09:30.160 --> 09:33.800
haben für Daten und Programme, damit man nicht einfach so in den

09:33.800 --> 09:35.320
Programmspeicher reinschreibt.

09:36.840 --> 09:40.320
Außerdem, wenn sie da getrennte Speicher haben potenziell, können sie

09:40.320 --> 09:45.160
halt gleichzeitig ein Datum und einen Befehl holen, potenziell ein

09:45.160 --> 09:46.160
bisschen schneller.

09:49.180 --> 09:53.020
Und jetzt kommen also noch drei Abschnitte.

09:53.220 --> 09:58.700
Erstmal die meisten der Maschinenbefehle, die für diesen

09:58.700 --> 10:03.740
Modellprozessor vorgesehen sind und die dann die Simulatoren für das

10:03.740 --> 10:05.360
Ding auch wirklich verarbeiten können.

10:06.140 --> 10:07.920
Gucken wir uns so ein bisschen an, was die tun.

10:09.500 --> 10:13.780
Und dann das zweite ist, dass wir uns hinterher angucken, jetzt auf

10:13.780 --> 10:17.320
einem noch niedrigeren Niveau, was passiert denn da alles in dem

10:17.320 --> 10:20.200
Prozessor, um einen Befehl zu holen, ihn auszuführen.

10:23.980 --> 10:31.100
Und am Ende dann so ein kleines bisschen größeres Programm, wo Sie

10:31.100 --> 10:33.180
sehen, dass ein paar von den Befehlen nicht offensichtlich nützlich

10:33.180 --> 10:33.540
sind.

10:35.980 --> 10:44.580
So, diese Maschinenbefehle, das sind also Befehle, die dazu führen,

10:44.720 --> 10:49.980
dass irgendwelche ganz, ganz einfachen Operationen in diesem einfachen

10:49.980 --> 10:57.140
Prozessor durchgeführt werden, nämlich zum Beispiel einen Wert, so 24

10:57.140 --> 11:01.020
Bit hier, aus dem Speicher holen und in den Akkumulator, im

11:01.020 --> 11:02.220
Akkumulator ablegen.

11:04.160 --> 11:07.760
Oder einen Wert, den man schon im Akkumulator hat und einen, den man

11:07.760 --> 11:13.340
noch aus dem Speicher holt, nehmen und sozusagen die Bitmuster

11:13.340 --> 11:17.200
interpretiert als Zweierkomplementdarstellung von Zahlen nehmen, die

11:17.200 --> 11:20.260
repräsentierten Zahlen addieren und die Zweierkomplementdarstellung

11:20.260 --> 11:24.020
von der Summe produzieren als Ergebnis, also sowas wie Addition.

11:25.720 --> 11:31.820
Und dann werden Sie sehen, ja, also das Normale ist, man holt sich die

11:31.820 --> 11:34.560
Maschinenbefehle einen nach dem anderen aufs hintereinanderliegenden

11:34.560 --> 11:38.340
Speicherstellen, aber manchmal möchte man auch von dieser banalen

11:38.340 --> 11:41.520
Reihenfolge abweichen und dafür braucht man dann auch noch

11:41.520 --> 11:42.280
Maschinenbefehle.

11:45.580 --> 11:50.000
So, das muss man alles irgendwie hinschreiben und rein theoretisch auf

11:50.000 --> 11:54.040
dem Niveau von MIMA, ja, jeder Maschinenbefehl ist einfach ein 24-Bit

11:54.040 --> 11:54.440
-Wort.

11:55.240 --> 11:59.240
Da kann man natürlich sowas da hinschreiben, aber kein Mensch kann das

11:59.240 --> 12:01.540
lesen, was soll das bedeuten.

12:02.100 --> 12:06.140
Und deswegen benutzen wir so eine symbolische Notation, zum Beispiel

12:06.140 --> 12:11.340
die ersten Bit hier oben von dieser Bitfolge 0010 besagen, das ist ein

12:11.340 --> 12:14.520
Maschinenbefehl, für den schreiben wir kurz STV, kommt gleich da

12:14.520 --> 12:15.300
unten, was das ist.

12:15.880 --> 12:21.480
Und die restlichen 20 Bit sind irgendwie so ein Argument, also in dem

12:21.480 --> 12:23.460
Fall hier jetzt eine Speicheradresse.

12:27.760 --> 12:32.800
Und das sind also ganz viele Nullen und hinten 101010 und führende

12:32.800 --> 12:35.460
Nullen bei dem, was wir so hinschreiben, lassen wir auch der

12:35.460 --> 12:37.780
Einfachheit halber mal weg, einfach damit das so ein bisschen

12:37.780 --> 12:38.600
übersichtlicher ist.

12:39.060 --> 12:42.640
Und statt binär 101010 schreibe ich dann auch einfach die

12:42.640 --> 12:45.320
Dezimaldarstellung von der Zahl hin, 42, ja.

12:45.320 --> 12:51.200
Man muss da ein bisschen aufpassen, zwei Komplementdarstellungen,

12:51.400 --> 12:55.380
falls da eine negative Zahl ist und so, aber wir machen hier ganz

12:55.380 --> 12:56.000
Eimsache Dinge.

12:56.980 --> 12:59.480
Also wir schreiben sowas dahin und dann muss ich irgendwann noch

12:59.480 --> 13:02.320
erklären, wie die Maschinenbefehle funktionieren.

13:03.480 --> 13:05.920
Und dann will ich manchmal sowas sagen wie, hier wird der Wert

13:05.920 --> 13:09.600
genommen, der im Hauptspeicher an Adresse sowieso steht.

13:10.440 --> 13:14.280
Und dafür schreibe ich groß M wie Memory von und dann in runden

13:14.280 --> 13:15.980
Klammern steht halt die Adresse.

13:18.120 --> 13:25.140
So, und dann gibt es jetzt erstmal drei Befehle, um irgendwie Daten zu

13:25.140 --> 13:26.060
transportieren.

13:27.240 --> 13:33.580
Und das Einfachste ist ein Befehl, der heißt, der wird abgekürzt LDC

13:33.580 --> 13:43.900
für Load Constant und dann kann man noch dahinter 20 Bit schreiben und

13:43.900 --> 13:48.260
das wird dann als Zahl interpretiert und zwar an dieser Stelle nicht

13:48.260 --> 13:51.820
als Zweierkomplementzahl, sondern einfach als ganz normale nicht

13:51.820 --> 13:55.660
negative Binärdarstellung mit 20 Bit einer Zahl.

13:55.920 --> 13:59.000
Also das, was durch dieses Bitmuster hier hinten repräsentiert wird

13:59.000 --> 14:03.360
bei LDC, ist immer eine nicht negative ganze Zahl und die wird dann

14:03.360 --> 14:08.880
genommen und in den Akkumulator geschoben und der Akkumulator ist 24

14:08.880 --> 14:13.200
Bit groß, die 20 Bit hinten sind die aus dem Maschinenbefehl und vorne

14:13.200 --> 14:15.980
die 4 Bit werden ergänzt, werden einfach auf 0 gesetzt.

14:17.500 --> 14:20.140
Also Sie haben keine Chance, dann ein Minus 1 in den Akkumulator

14:20.140 --> 14:21.240
direkt reinzukriegen.

14:22.460 --> 14:25.960
Aber Sie können irgendwelche harmlosen Konstanten wie 0 oder 1 oder

14:25.960 --> 14:28.960
was, können Sie einfach in den Akkumulator transportieren.

14:29.400 --> 14:32.120
Und welcher Wert, das steht hier direkt im Maschinenbefehl.

14:34.880 --> 14:36.600
So, das ist die erste Möglichkeit.

14:36.720 --> 14:39.120
Die zweite Möglichkeit, einen Wert in den Akkumulator zu bekommen, ist

14:39.120 --> 14:45.660
dieser Maschinenbefehl LDV, Load Value From Address oder so.

14:46.400 --> 14:53.280
Und da ist hintendran auch wieder eine Folge von 20 Bits und bei LDV

14:53.280 --> 14:59.140
wird die interpretiert als Adresse des Hauptspeichers, also eine Zahl

14:59.140 --> 15:01.200
zwischen 0 und 2 hoch 20 minus 1.

15:02.400 --> 15:06.260
Und LDV, irgendeine Adresse, führt dazu, dass eben im Hauptspeicher

15:06.260 --> 15:10.340
der Wert, der an dieser angegebenen Adresse liegt, geholt wird und im

15:10.340 --> 15:11.720
Akkumulator abgelegt wird.

15:12.420 --> 15:15.060
Und wir stellen uns vor, im Hauptspeicher, die Werte, die da kommen,

15:15.200 --> 15:18.840
sind 24 Bit groß, das passt genau in den Akkumulator, alles ist gut.

15:21.340 --> 15:23.900
Und so wie man etwas aus dem Hauptspeicher holen kann und in den

15:23.900 --> 15:26.620
Akkumulator laden kann, kann man auf den umgekehrten Weg gehen.

15:26.760 --> 15:30.820
Da gibt es also einen Maschinenbefehl STV für Store Value an

15:30.820 --> 15:31.660
irgendeine Adresse.

15:32.500 --> 15:37.660
Und da auch wieder Adresse, 21 Bit Wert, der als Adresse einer Stelle

15:37.660 --> 15:39.080
im Hauptspeicher interpretiert wird.

15:39.220 --> 15:42.960
Und da wird der Akkumulatorinhalt an die entsprechende Stelle im

15:42.960 --> 15:43.940
Speicher transportiert.

15:45.180 --> 15:47.680
Also Sie können was aus dem Speicher holen, in den Akkumulator laden,

15:47.800 --> 15:50.100
dann vielleicht irgendwas rechnen und dann den Wert zurück

15:50.100 --> 15:51.480
transportieren in den Hauptspeicher.

15:57.120 --> 16:00.360
Stellen Sie sich vor, der erste Maschinenbefehl, den der Prozessor aus

16:00.360 --> 16:04.980
welchen Gründen auch immer ausführt, ist LDC 13, also Load Constant

16:04.980 --> 16:06.040
13.

16:07.020 --> 16:10.120
Was dann hinterher der Fall ist, ist, dass im Akkumulator eben der

16:10.120 --> 16:11.040
Wert 13 steht.

16:13.520 --> 16:16.220
Wie die CPU das hinkriegt, das sehen wir dann später.

16:16.460 --> 16:17.520
Aber das ist der Effekt.

16:18.800 --> 16:22.200
Und wenn Sie dann zum Beispiel als nächstes den Befehl STV 46

16:22.200 --> 16:27.880
ausführen, also Store Value at Address 46, dann führt das dazu, dass

16:27.880 --> 16:31.960
der Wert, der gerade im Akkumulator rumliegt, vor der Ausführung

16:31.960 --> 16:35.960
dieses Befehls, das ist also hier die 13, in den Hauptspeicher

16:35.960 --> 16:39.800
transportiert wird und an der Stelle mit der Adresse 46 abgelegt wird.

16:40.840 --> 16:44.800
Und dann wissen Sie, jetzt liegt an Stelle 46 im Hauptspeicher die 13.

16:45.320 --> 16:46.940
Was da vorher war, weiß keiner.

16:46.940 --> 16:55.750
Und dann können Sie als nächstes wieder mit Load Constant die 25 in

16:55.750 --> 16:57.070
den Akkumulator schreiben.

16:57.850 --> 16:59.310
Und das, was vorher da stand, ist halt weg.

16:59.910 --> 17:02.510
Ach so, das wollte ich noch sagen, bei dem Store Value hinterher die

17:02.510 --> 17:05.890
13 steht im Hauptspeicher und im Akkumulator steht sie immer noch.

17:06.110 --> 17:08.990
Also es ist nicht so, dass das da weggenommen wird und dahin

17:08.990 --> 17:09.710
transportiert wird.

17:10.290 --> 17:12.150
Hinterher ist der Akkumulator leer oder so.

17:12.530 --> 17:13.350
Das bleibt da stehen.

17:13.750 --> 17:15.790
Der Wert wird kopiert in den Hauptspeicher.

17:16.690 --> 17:20.330
Dann können Sie zum Beispiel mit Load Constant 25 die 25 in den

17:20.330 --> 17:23.030
Akkumulator tun.

17:23.650 --> 17:28.170
Und wenn Sie dann sagen Store Value at Address 47, dann wird eben die

17:28.170 --> 17:33.310
25 in den Hauptspeicher transportiert und an der Stelle mit Adresse 47

17:33.310 --> 17:33.950
abgelegt.

17:34.230 --> 17:35.310
Dann steht da die 25.

17:38.090 --> 17:41.930
Und wir wollen uns vorstellen, dass der Hauptspeicher hier so

17:41.930 --> 17:44.710
funktioniert, wie wir uns das im letzten Kapitel auch plausibel

17:44.710 --> 17:48.750
gemacht hatten, wenn man an einer Stelle was schreibt, an anderen

17:48.750 --> 17:50.530
Stellen ändert sich dadurch nichts.

17:52.910 --> 17:55.530
Das ist irgendwie so etwas, was man gerne hätte.

17:56.470 --> 18:00.450
Und deswegen, wenn Sie jetzt im nächsten Schritt den Befehl ausführen,

18:01.250 --> 18:08.410
Load Value from Address 46, dann in 46 steht immer noch die 13 und

18:08.410 --> 18:10.750
dann, wenn der Befehl ausgeführt wird, wird eben zum Speicher

18:10.750 --> 18:14.430
gegangen, bei Adresse 46 nachgeguckt, da die 13 geholt, in den

18:14.430 --> 18:17.950
Akkumulator transportiert und dann ist da die 25 überschrieben und da

18:17.950 --> 18:18.890
steht jetzt wieder die 13.

18:20.690 --> 18:23.790
Also wenn man diese Maschinenbefehle in dieser Reihenfolge ausführt,

18:23.870 --> 18:27.610
dann kann man sicher sein, hinterher im Akkumulator steht 13, anstelle

18:27.610 --> 18:30.990
46 im Speicher steht 13, anstelle 47 steht 25.

18:32.810 --> 18:35.530
Und das ist erstmal, jetzt habe ich völlig offen gelassen, wie kommt

18:35.530 --> 18:38.550
das denn dazu, dass der Prozessor nun ausgerechnet diese Befehle in

18:38.550 --> 18:39.730
dieser Reihenfolge ausführt.

18:39.730 --> 18:43.130
Nehmen wir einfach mal an, es passiert in dieser Reihenfolge, warum

18:43.130 --> 18:43.610
auch immer.

18:46.290 --> 18:51.250
Also haben Sie hier diese einfachen Befehle, um Werte hin und her zu

18:51.250 --> 18:54.990
schieben oder explizit einen Wert in den Akkumulator zu laden.

19:00.530 --> 19:04.890
Manchmal hat man etwas kompliziertere Anforderungen, um Werte durch

19:04.890 --> 19:05.890
die Gegend zu schieben.

19:08.580 --> 19:12.620
Wir werden gleich ein Beispiel sehen und am Ende das Beispielprogramm

19:12.620 --> 19:14.660
macht glaube ich auch sowas.

19:16.500 --> 19:20.760
Und dafür finden Sie bei MIMA und auch bei realen Prozessoren

19:20.760 --> 19:25.360
irgendwie Maschinenbefehle, die heißen hier LD, IV und ST, IV.

19:25.880 --> 19:29.720
LD und ST wieder weisen hin auf Load und Store.

19:30.540 --> 19:35.120
Und jetzt aber nicht V, sondern IV und das I steht für Indirect.

19:36.220 --> 19:39.640
Und das V wieder für Value, das heißt wir greifen wieder auf den

19:39.640 --> 19:40.320
Speicher zu.

19:41.100 --> 19:45.120
Und die beiden Maschinenbefehle haben auch dann hintendran eben so ein

19:45.120 --> 19:46.740
20 -Bit-Muster eine Adresse.

19:48.280 --> 19:51.400
Aber was mit der Adresse veranstaltet wird, ist komplizierter.

19:53.220 --> 19:59.620
Bei Load Indirect wird die Adresse genommen, es wird gelesen im

19:59.620 --> 20:03.100
Speicher unter der Adresse, was steht denn da, da kommt irgendein Wert

20:03.100 --> 20:03.520
zurück.

20:03.520 --> 20:07.040
Und bei Load Value wäre das jetzt der Wert, der in den Akkumulator

20:07.040 --> 20:07.420
kommt.

20:07.560 --> 20:13.440
Bei Load Indirect wird dieser Wert genommen, zurechtgestutzt auf 20

20:13.440 --> 20:16.820
-Bit, die vordersten 4-Bit werden weggeworfen und dieser Wert wird

20:16.820 --> 20:20.220
wieder als Adresse benutzt und jetzt wird unter der Adresse nochmal im

20:20.220 --> 20:23.560
Speicher nachgeguckt, welchen Wert haben wir denn da und der wird

20:23.560 --> 20:25.020
geholt und der kommt in den Akkumulator.

20:25.620 --> 20:32.000
Also im Akkumulator landet das, was im Speicher an der Adresse steht,

20:32.000 --> 20:34.240
die im Speicher an Adresse ADR steht.

20:35.080 --> 20:36.140
Also Sie haben da zwei Speicherzugriffe.

20:37.260 --> 20:40.340
Beim ersten holen Sie die Adresse, die Sie interessiert und beim

20:40.340 --> 20:42.360
zweiten den Wert aus der interessierenden Adresse.

20:43.100 --> 20:45.260
Und bei Store Value Indirect umgekehrt.

20:45.960 --> 20:50.040
Sie schreiben den Akkumulatorinhalt an die Adresse, die Sie finden im

20:50.040 --> 20:52.140
Hauptspeicher unter der Adresse ADR.

20:54.220 --> 21:01.180
Und bei dem ersten Speicherzugriff, da kommt ein 24-Bit-Wert und wird

21:01.180 --> 21:07.620
aber als Adresse interpretiert und das heißt, nach meinem Verständnis,

21:07.700 --> 21:11.080
die vier höchstwertigen Bits werden einfach mitgeworfen, damit man

21:11.080 --> 21:11.800
eine Adresse hat.

21:12.520 --> 21:15.820
Wofür das gut ist, werden Sie dann auch im Programmieren bald sehen.

21:17.080 --> 21:19.560
Und um nochmal den Unterschied ganz deutlich zu machen.

21:19.760 --> 21:22.640
Also stellen Sie sich vor, im Hauptspeicher an Adresse 46 haben Sie

21:22.640 --> 21:25.840
eine 81 stehen und an Adresse 81 eine 25.

21:27.040 --> 21:31.480
Wenn Sie den Befehl LDV, den wir vorher hatten, ohne das Indirect,

21:32.020 --> 21:36.940
LDV46 ausführen, dann heißt das, guck im Speicher unter Adresse 46

21:36.940 --> 21:42.000
nach, da steht die 81, und hol die und leg sie in den Akkumulator und

21:42.000 --> 21:44.280
dann landet die 81 halt im Akkumulator.

21:45.960 --> 21:47.040
Dann liegt sie da.

21:48.360 --> 21:55.420
Wenn Sie den Load Indirect Befehl ausführen, Adresse 46, dann gehen

21:55.420 --> 21:58.740
Sie in den Hauptspeicher, gucken, was steht in Adresse 46, finden Sie

21:58.740 --> 22:04.220
da die 81 und dann interpretieren Sie das nochmal als Adresse und

22:04.220 --> 22:07.480
schauen jetzt im Hauptspeicher unter Adresse 81 nach, was steht denn

22:07.480 --> 22:12.480
da, da steht die 25 und dann landet die 25 im Akkumulator, was

22:12.480 --> 22:14.680
offensichtlich etwas anderes ist als bei LDV.

22:14.680 --> 22:17.740
Und diese Vorgehensweise nennt man indirekte Adressierung.

22:18.540 --> 22:22.580
Im Maschinenbefehl steht nicht die Adresse, unter der man den Wert

22:22.580 --> 22:25.580
findet, sondern im Maschinenbefehl steht nur die Adresse, unter der

22:25.580 --> 22:28.140
man im Hauptspeicher die Adresse findet, unter der man den Wert

22:28.140 --> 22:28.880
findet, der einen interessiert.

22:29.760 --> 22:31.980
So viel noch zu Datentransporten.

22:32.420 --> 22:35.580
Und hier war es für Load und für Store Indirect analog.

22:36.360 --> 22:38.820
Jetzt will man nicht nur Daten hin- und herschieben, man will sie auch

22:38.820 --> 22:39.500
mal verändern.

22:41.260 --> 22:43.160
Dafür gibt es auch ein paar Maschinenbefehle.

22:45.380 --> 22:48.680
Ach so, und übrigens, ich weiß nicht, ob das eine gute Stelle ist, um

22:48.680 --> 22:49.320
das einzufügen.

22:50.560 --> 22:53.600
Hier, das ist also jetzt so ein idealisierter Prozessor.

22:54.680 --> 23:02.160
Hier ist das, was ein Compiler für die CPU in meinem Desktop-Rechner

23:02.160 --> 23:02.420
macht.

23:02.640 --> 23:03.960
Das sieht so ähnlich aus.

23:04.120 --> 23:06.740
Da stehen hier links auch so Maschinenbefehle, die heißen jetzt

23:06.740 --> 23:07.560
irgendwie anders.

23:09.580 --> 23:13.460
MOVQ, das ist auch so, das MOV kommt von Move, da werden irgendwelche

23:13.460 --> 23:16.880
Daten transportiert von ich weiß nicht wo nach irgendwo anders.

23:17.640 --> 23:20.140
Also ist alles ein bisschen komplizierter, weil der Prozessor

23:20.140 --> 23:21.500
komplizierter ist als die MIMA.

23:22.440 --> 23:25.040
Aber im Prinzip sieht das genau so aus auf der Ebene.

23:25.300 --> 23:28.500
Das ist wirklich etwas, was Sie dann noch nehmen können, noch ein

23:28.500 --> 23:31.640
bisschen verarbeiten und dann einem Prozessor, einem echten Prozessor

23:31.640 --> 23:33.620
geben können zum Ausführen.

23:35.000 --> 23:40.520
So, wird jetzt hier die MIMA, wie gesagt, so ganz einfach gebaut,

23:40.960 --> 23:43.060
beschränkt auf das Wesentliche.

23:43.120 --> 23:49.120
Deswegen gibt es explizit auch nur einen Befehl für eine normale

23:49.120 --> 23:51.540
arithmetische Operation, nämlich für die Addition.

23:52.620 --> 23:56.800
Und zwar Addition in dem Sinne, die 24-Bit-Werte werden als

23:56.800 --> 24:00.100
Zweierkomplement -Darstellung von zwei Zahlen interpretiert.

24:01.460 --> 24:04.840
Und was rauskommt bei der Operation ist die Zweierkomplement

24:04.840 --> 24:05.820
-Darstellung der Summe.

24:07.240 --> 24:10.560
Und bei Überlauf wird Bits abgeschnitten oder so.

24:11.100 --> 24:14.860
Also es gibt einen Maschinenbefehl, der heißt Add und hintendran

24:14.860 --> 24:16.040
wieder eine Speicheradresse.

24:16.220 --> 24:20.100
Und was passiert ist, man braucht ja zwei Argumente zum Addieren.

24:20.400 --> 24:23.380
Der eine Wert kommt aus dem Akkumulator, der andere aus dem

24:23.380 --> 24:24.020
Hauptspeicher.

24:24.020 --> 24:26.640
Und dann wird eben an der Adresse nachgeguckt, die hier steht.

24:28.000 --> 24:30.900
Und dann wird, in Anführungszeichen, die Summe gebildet, wie ich das

24:30.900 --> 24:31.560
gerade gesagt habe.

24:31.660 --> 24:35.020
Ja, man stellt sich die Dinger als Zweierkomplement-Darstellungen vor

24:35.020 --> 24:39.080
und die Summe wird wieder in den Akkumulator gelegt.

24:41.640 --> 24:43.600
Das ist also die einzige arithmetische Operation.

24:43.800 --> 24:47.100
Und dann gibt es so welche für logische, in Anführungszeichen,

24:47.200 --> 24:48.180
Operationen.

24:48.180 --> 24:51.820
Also stellen Sie sich vor, eine Eins steht für True oder Wahr, eine

24:51.820 --> 24:53.600
Null für Falsch oder False.

24:54.640 --> 24:57.880
Und dann haben Sie so Operationen für logisches Und.

24:58.580 --> 25:02.940
Der Maschinenbefehl heißt And, Or für Oder, Exor für exklusives Oder,

25:03.080 --> 25:04.760
das heißt Addition, Modulo 2.

25:07.340 --> 25:12.420
Und da wird immer ein 24-Bit-Muster aus dem Akkumulator genommen, ein

25:12.420 --> 25:14.740
24 -Bit-Muster aus dem Hauptspeicher geholt.

25:15.560 --> 25:19.040
Nebeneinander gehalten sozusagen und dann stellenweise immer zwei Bits

25:19.040 --> 25:22.020
gemäß der logischen Operation miteinander verknispelt.

25:22.160 --> 25:26.020
Und raus kommt ein neuer 24-Bit-Vektor und das ist das Ergebnis.

25:26.740 --> 25:30.460
Und die Ergebnisse liegen immer hinterher im Akkumulator und das, was

25:30.460 --> 25:31.400
vorher da war, ist weg.

25:34.480 --> 25:37.500
Also logisches Und, logisches Oder und exklusives Oder.

25:39.500 --> 25:42.800
Ach so, und diese Befehle heißen typischerweise arithmetisch-logische

25:42.800 --> 25:46.060
Befehle und in der echten CPU haben Sie dann auch welche für

25:46.060 --> 25:47.700
Subtraktion, Multiplikation.

25:49.140 --> 25:52.540
Wenn Sie das zu Fuß selber programmieren wollen, ist irgendwie nicht

25:52.540 --> 25:53.060
so schön.

25:54.560 --> 25:57.660
Das will man schnell, also nicht so schnell, man will es schnell

25:57.660 --> 25:58.020
haben.

25:58.780 --> 26:01.140
Und Division und, und, und, und, und, und.

26:01.740 --> 26:04.840
Und vielleicht nicht nur für Zahlen in zweier Komplementdarstellung,

26:04.960 --> 26:06.160
sondern auch noch für was anderes.

26:08.560 --> 26:11.120
So, hier ist ein hochkompliziertes Programm.

26:13.680 --> 26:15.960
Es beginnt, stellen Sie sich vor, als erstes wird der Maschinenbefehl

26:15.960 --> 26:18.120
ausgeführt, Load Constant 0.

26:18.900 --> 26:21.800
Da wird also explizit die 0 in den Akkumulator geschrieben.

26:22.280 --> 26:26.360
Und bitte niemals, weder bei der MIMA noch in Ihren Java-Programmen in

26:26.360 --> 26:30.220
Programmieren oder sonst irgendwo, gehen Sie davon aus, dass Sie

26:30.220 --> 26:35.300
wissen, vorher, ohne dass Sie was getan haben, an gewissen Stellen

26:35.300 --> 26:37.940
stünden bestimmt ganz gewisse Werte.

26:39.240 --> 26:42.700
Wenn Sie Speicher benutzen, initialisieren Sie den immer.

26:43.200 --> 26:46.900
Gehen Sie nicht davon aus, dass magisch schon am Anfang irgendetwas

26:46.900 --> 26:47.840
irgendwie ist.

26:48.920 --> 26:50.380
Es ist nicht in aller Regel.

26:51.380 --> 26:54.700
Deswegen also explizit hier die 0 in den Akkumulator, damit man weiß,

26:54.760 --> 26:55.360
was drin ist.

26:56.080 --> 26:59.700
Und angenommen, wir haben an den Streicherstellen 46, 47, 48 und 49

26:59.700 --> 27:02.080
die Werte 11, 22, 33 und 44.

27:02.700 --> 27:03.400
Also schon vorher.

27:04.680 --> 27:07.840
Also hier sage ich jetzt genau, irgendjemand hat sie halt vorher da

27:07.840 --> 27:08.380
reingemacht.

27:09.940 --> 27:14.000
So, wenn jetzt der Befehl kommt, addiere 46, dann wird also der

27:14.000 --> 27:18.340
bisherige Akkumulatorinhalt 0 genommen und addiert mit dem Wert, der

27:18.340 --> 27:21.800
unter Adresse 46 im Hauptspeicher zu finden ist, das ist die 11.

27:22.360 --> 27:23.620
0 plus 11 ist 11.

27:24.360 --> 27:29.900
Wenn dann als nächstes addiere 47 kommt, dann wird also der bisherige

27:29.900 --> 27:33.920
Akkumulatorinhalt 11 genommen und addiert zu dem Wert, den man im

27:33.920 --> 27:36.900
Speicher unter Adresse 47 findet, das ist die 22.

27:37.600 --> 27:39.520
11 und 22 gibt 33.

27:40.440 --> 27:44.900
Und wenn Sie dann addieren den Wert, den Sie unter Adresse 48 finden,

27:45.040 --> 27:46.020
das ist die 33.

27:46.240 --> 27:48.560
Zusammen mit den 33 bisher gibt es 66.

27:49.240 --> 27:53.020
Und wenn Sie dann noch bei 49 nachgucken, da steht die 44 und die auch

27:53.020 --> 27:56.840
noch drauf addieren auf die 66, sind Sie bei 110.

27:57.580 --> 28:01.180
So können Sie also, wenn Sie wollen, mehrere Werte, die an

28:01.180 --> 28:03.880
aufeinanderfolgenden Stellen liegen, aufaddieren.

28:05.400 --> 28:10.360
Ist aber ein bisschen mühsam, ja, also wenn das jetzt nicht vier Werte

28:10.360 --> 28:13.600
wären, sondern eine Million, dann müssten Sie da eine Million

28:13.600 --> 28:15.420
Maschinenbefehle untereinander hinschreiben.

28:15.780 --> 28:18.600
Das klingt blöd, ja, das will man natürlich nicht haben.

28:20.640 --> 28:22.400
Wir werden sehen, dass es besser geht.

28:24.260 --> 28:27.780
Also das wäre so ein einfaches Programm, ja, und Addition ist das

28:27.780 --> 28:29.220
Einzige, was wir hier geschenkt kriegen.

28:30.240 --> 28:31.820
Alles andere muss man sich selber bauen.

28:34.040 --> 28:36.380
Das ist aber zum Teil nicht so ganz schwierig.

28:37.600 --> 28:40.520
Das eine ist, es gibt einen Maschinenbefehl, der heißt NOT.

28:41.600 --> 28:45.160
Da wird einfach der Akkumulatorinhalt genommen, aus jeder 0 eine 1

28:45.160 --> 28:46.600
gemacht, aus jeder 1 eine 0.

28:46.900 --> 28:50.420
Das gibt einen neuen, offensichtlich anderen Wert und das ist der neue

28:50.420 --> 28:51.500
Wert für den Akkumulator.

28:51.500 --> 28:56.360
Und es gibt einen Maschinenbefehl, der nimmt die 24 Bit im

28:56.360 --> 29:01.700
Akkumulator, das Bit, das ganz hinten steht, wird weggenommen, alles

29:01.700 --> 29:04.520
eins nach rechts geschoben und das, was man hinten weggenommen hat,

29:04.580 --> 29:07.240
vorne dran geklebt, also so ein Bit im Kreis.

29:08.240 --> 29:10.720
Alle Bits im Akkumulator, ein Bit nach rechts, Richtung

29:10.720 --> 29:13.660
niedrigwertiges Bit und das von ganz hinten wandert nach ganz vorne.

29:16.040 --> 29:19.120
Abgekürzt RAR für Rotate Accumulator Right.

29:20.300 --> 29:24.440
Weil die Bits im Wesentlichen nach rechts rutschen und Rotate, weil

29:24.440 --> 29:28.060
das nicht verloren geht, das X0, sondern hinterher im Kreis vorne dran

29:28.060 --> 29:28.640
geklebt wird.

29:29.960 --> 29:33.880
Und man kann auch mal nachgucken, ob zwei Werte gleich sind oder

29:33.880 --> 29:34.220
nicht.

29:35.600 --> 29:41.160
Es gibt den Befehl EQL für Equal und Argument jetzt hier wieder eine

29:41.160 --> 29:43.000
Adresse im Hauptspeicher.

29:44.440 --> 29:45.920
Und was wird da gemacht?

29:46.060 --> 29:48.480
Da wird der Wert aus dem Akkumulator genommen.

29:48.480 --> 29:51.660
Es wird unter der angegebenen Adresse im Hauptspeicher nachgeguckt,

29:51.760 --> 29:52.600
welcher Wert steht da.

29:52.700 --> 29:55.840
Der wird geholt und dann werden die beiden Werte verglichen.

29:56.080 --> 30:00.300
Und wenn die beiden gleich sind, das, was im Akku war und das, was im

30:00.300 --> 30:05.780
Hauptspeicher an Adresse ADR steht, dann werden im Akkumulator alle

30:05.780 --> 30:06.840
Bits auf 1 gesetzt.

30:10.300 --> 30:13.220
Und wenn die beiden Werte verschieden sind, werden die Bits im

30:13.220 --> 30:14.680
Akkumulator alle auf 0 gesetzt.

30:15.700 --> 30:20.100
Und zur Erinnerung, dieses Bitmuster, alles ist 1, wenn Sie das

30:20.100 --> 30:22.860
interpretieren als Zweierkomplement darstellen, das ist die Zahl minus

30:22.860 --> 30:24.180
1, nur so am Rande.

30:26.540 --> 30:30.440
So, also man kann auch zwei Werte vergleichen und hat dann hinterher,

30:32.040 --> 30:35.600
man kann an dem Wert im Akkumulator ablesen, was ist beim Vergleich

30:35.600 --> 30:37.340
passiert, waren die gleich oder ungleich.

30:38.560 --> 30:39.000
Gut.

30:41.100 --> 30:43.380
So, jetzt bis hierher, ich habe vorhin auch immer gesagt, naja,

30:43.960 --> 30:47.100
stellen wir uns vor, diese Maschinenbefehle würden aus welchen Gründen

30:47.100 --> 30:49.600
auch immer in dieser Reihenfolge abgearbeitet.

30:50.800 --> 30:53.500
Jetzt stellen wir uns mal die Frage, ja, warum denn in dieser

30:53.500 --> 30:54.260
Reihenfolge?

30:55.340 --> 30:59.300
Na, der Punkt ist, zu jedem Zeitpunkt, was Sie in dem

30:59.300 --> 31:02.680
Instruktionsregister in der CPU haben, ist immer nur ein

31:02.680 --> 31:03.480
Maschinenbefehl.

31:05.120 --> 31:06.680
Der wird abgearbeitet.

31:07.620 --> 31:11.200
Und dann muss der nächste Maschinenbefehl, also nicht nur die Daten,

31:11.320 --> 31:13.820
sondern auch immer der nächste Maschinenbefehl aus dem Hauptspeicher

31:13.820 --> 31:14.660
geholt werden.

31:18.460 --> 31:23.100
Und dann ist die Frage, wo kommt der nächste Maschinenbefehl her, an

31:23.100 --> 31:24.120
welcher Stelle steht der?

31:25.540 --> 31:29.540
Also es gibt dieses Instruktionsadressregister, da steht immer die

31:29.540 --> 31:32.080
Adresse des nächsten Maschinenbefehls drin, rechtzeitig.

31:33.420 --> 31:36.920
Und das Normale ist aber, das wird immer einfach eins hochgezählt.

31:36.920 --> 31:42.380
Das heißt, wenn Sie Maschinenbefehle an aufeinanderfolgenden Adressen

31:42.380 --> 31:45.640
im Hauptspeicher ablegen, also hier die führenden Nullen habe ich mal

31:45.640 --> 31:50.200
alle weggelassen bei den Adressen, ja, an Adresse 5, LoadConstant 7,

31:50.520 --> 31:56.460
an Adresse 6, StoreValue etwas, 60, Adresse 7, Adresse 8.

31:57.440 --> 32:01.280
Wenn aus irgendwelchen Gründen der Prozessor dabei ist, jetzt erstmal

32:01.280 --> 32:06.140
hier diesen Befehl LoadConstant 7 auszuführen, weil das

32:06.140 --> 32:10.340
Instruktionsadressregister sagt, Adresse 5 interessiert uns.

32:11.300 --> 32:15.700
Dann wird eben der Befehl ausgeführt und dann im nächsten Schritt wird

32:15.700 --> 32:19.540
einfach der an der nächsten Speicherstelle genommen, an Adresse 6 und

32:19.540 --> 32:21.960
dann der an Adresse 7 und dann der an Adresse 8.

32:23.560 --> 32:27.500
Also das ist das Normale, man holt die Befehle aus

32:27.500 --> 32:31.940
aufeinanderfolgenden Stellen im Hauptspeicher, weil das Register, das

32:31.940 --> 32:34.920
einem immer sagt, wo ist die Adresse des nächsten Befehls, einfach

32:34.920 --> 32:36.440
immer um 1 hochgezählt wird.

32:37.320 --> 32:38.600
Wir sehen das gleich noch genauer.

32:40.720 --> 32:43.080
Und das muss eben auch irgendwie passieren.

32:43.960 --> 32:48.000
Und weil das der Normalfall ist, hat kein Mensch Lust, wenn er ein

32:48.000 --> 32:51.300
Stück Maschinenprogramm hinschreibt, vor jedem Maschinenbefehl eine

32:51.300 --> 32:55.560
Adresse zu schreiben, weil die konkreten Werte jetzt hier bei sowas

32:55.560 --> 32:57.980
auch völlig irrelevant sind, es ist nur wichtig, die stehen

32:57.980 --> 32:59.380
hintereinander im Hauptspeicher.

33:00.100 --> 33:03.520
Und deswegen lässt man die Adressen hier gerne mal weg, weil sie

33:03.520 --> 33:04.820
irgendwie nicht so wichtig sind.

33:06.500 --> 33:09.140
Also man lässt sie weg, da wo sie nicht wichtig sind.

33:13.320 --> 33:16.940
Und wie gesagt, der Prozessor muss dann also nicht nur immer diesen

33:16.940 --> 33:20.600
Maschinenbefehl ausführen, den er ausführen soll, er muss auch noch

33:20.600 --> 33:24.040
dafür sorgen, dass dieses Instruktionsadressregister, wo drin steht,

33:24.640 --> 33:28.680
wo kommt der nächste Maschinenbefehl her, dass das Ding um eins

33:28.680 --> 33:29.520
hochgezählt wird.

33:29.740 --> 33:34.160
Noch mehr Arithmetik intern, ohne dass Sie selber sich drum kümmern

33:34.160 --> 33:34.940
wollen oder müssen.

33:37.280 --> 33:42.000
Also die normale Reihenfolge einfach von aufeinanderfolgenden

33:42.000 --> 33:42.300
Adressen.

33:44.440 --> 33:48.920
Als sei denn, man sagt explizit, jetzt will ich aber mal nicht den

33:48.920 --> 33:51.360
nächsten Maschinenbefehl von der nächsten Adresse, sondern irgendwo

33:51.360 --> 33:51.740
anders.

33:52.560 --> 33:56.860
Und dann sind wir hier bei Befehlen, mit denen Sie beeinflussen

33:56.860 --> 34:01.080
können, wo kommt der nächste Maschinenbefehl her.

34:01.160 --> 34:05.500
Also Sie können Einfluss nehmen auf die Reihenfolge der

34:05.500 --> 34:05.800
Programmabarbeitung.

34:07.020 --> 34:11.700
Und der heimlose heißt Jump und dann steht dahinter eine Adresse 20

34:11.700 --> 34:11.980
Bit.

34:13.040 --> 34:19.020
Und die Bedeutung ist, Ausführung dieses Befehls bedeutet, der nächste

34:19.020 --> 34:22.100
Befehl kommt nicht aus der nächsten Speicherstelle, sondern der

34:22.100 --> 34:25.500
nächste Befehl kommt von der Adresse, die hier explizit angegeben ist.

34:26.660 --> 34:30.680
Und da steht also im Maschinenbefehl eine Programmadresse und das

34:30.680 --> 34:34.440
heißt, da ist es jetzt schon wichtig zu wissen, was steht denn jetzt

34:34.440 --> 34:35.700
an dieser Stelle im Programm.

34:37.020 --> 34:40.100
Und angenommen, hier steht also an Adressen 5, 6, 7 dieses

34:40.100 --> 34:44.920
LoadConstantStoreValue und dann Jump zu Adresse 56.

34:46.600 --> 34:52.280
Dann, wenn Adresse 56 steht, LoadConstant43 und an der nächsten Stelle

34:52.280 --> 34:56.420
dann addiere den Wert von Adresse 61.

34:58.120 --> 35:02.540
Sie fangen hier an bei Adresse 5 mit der Ausführung, dann wird also

35:02.540 --> 35:04.820
erstmal die 7 in den Akkumulator geladen.

35:05.800 --> 35:11.020
Die wird gespeichert an Adresse 61 und dann kommt die Ausführung von

35:11.020 --> 35:16.220
dem Befehl an Adresse 7, springe zu Adresse 56 und dann egal, was da

35:16.220 --> 35:19.380
dazwischen alles steht, ob das überhaupt sinnvoller Code ist oder

35:19.380 --> 35:22.600
nicht, der nächste Befehl, der ausgeführt wird, ist der, der an

35:22.600 --> 35:28.880
Adresse 56 steht und dann wird hier LoadConstant43 in den Akkumulator

35:28.880 --> 35:33.920
geladen und wenn jetzt da drauf addiert wird, der Wert aus Adresse 61,

35:34.100 --> 35:37.980
da haben wir vorhin die 7 abgespeichert, dann wird eben jetzt hier die

35:37.980 --> 35:40.840
7 auf die 43 addiert und dann hat man hinterher die 50.

35:41.420 --> 35:44.360
Ja und nach diesem Sprungbefehl, es geht wieder in der normalen

35:44.360 --> 35:49.040
Reihenfolge, ein zweiter, nächster, nächster, nächster Befehl,

35:49.200 --> 35:51.320
aufeinanderfolgenden Speicherstellen.

35:52.540 --> 35:59.180
Also Sie können hier so Teile des Programms, falls da denn überhaupt

35:59.180 --> 36:01.080
Programm steht, überspringen.

36:01.700 --> 36:05.160
Hier in dem Beispiel war es sozusagen von einer Adresse zu einer

36:05.160 --> 36:07.340
anderen Stelle mit einer höheren Adresse.

36:08.300 --> 36:11.060
Sie können auch zurückspringen zu etwas, wo Sie schon mal waren.

36:12.580 --> 36:18.220
Also was weiß ich, an Adresse 5 steht lauter die 1, addiere

36:18.220 --> 36:23.040
irgendeinen Wert von Adresse 61, speichere den neuen Wert, dann steht

36:23.040 --> 36:27.540
also an Adresse 61 ein 1 größerer Wert und dann der nächste Befehl ist

36:27.540 --> 36:31.980
an Adresse 8, springe zu Adresse 5, schwupp, dann sind wir wieder bei

36:31.980 --> 36:35.660
vorne, laden eine 1, addieren den Wert von Speicherstelle 61,

36:35.960 --> 36:39.180
speichern das zurück und springen wieder nach oben und holen wieder

36:39.180 --> 36:42.060
die 1 und wieder addieren wir den Wert und speichern den und springen

36:42.060 --> 36:42.540
wieder nach oben.

36:43.140 --> 36:48.360
Also das hört hier überhaupt nicht auf, weil es immer der vierte

36:48.360 --> 36:53.060
Befehl ist, springe zurück nach 5 und läuft und läuft und läuft und

36:53.060 --> 36:53.220
läuft.

36:58.020 --> 37:00.160
Also das Programm hält offensichtlich nie.

37:01.460 --> 37:03.660
Sie können sich mal fragen, ob sowas schön ist oder nicht.

37:05.320 --> 37:08.780
Ob Ihnen eine Anwendung einfällt, wo man möchte, dass ein Programm

37:08.780 --> 37:10.500
nicht aufhört.

37:12.200 --> 37:15.060
Bei so etwas wie Arithmetik möchte man, dass sie irgendwann zu Ende

37:15.060 --> 37:18.760
kommt, aber vielleicht gibt es ja auch Anwendungen, wo man das nicht

37:18.760 --> 37:19.060
möchte.

37:19.060 --> 37:20.780
Also das ist erlaubt.

37:20.960 --> 37:24.340
Und Sie könnten natürlich auch einen Sprungbefehl hinschreiben, wo als

37:24.340 --> 37:28.260
Sprungziel, als Adresse die Adresse dieses Sprungbefehls steht.

37:28.500 --> 37:30.140
Dann springt der Befehl immer zu sich selber.

37:30.400 --> 37:31.800
Da passiert ja überhaupt nichts mehr.

37:32.340 --> 37:34.920
Ist auch erlaubt, nur langweilig.

37:39.040 --> 37:41.960
Aber bei diesem Sprungbefehl, es passiert immer.

37:43.240 --> 37:46.100
Und jetzt, was man aber gerne haben möchte, das merkt man ziemlich

37:46.100 --> 37:49.580
schnell, ist, man möchte Einfluss nehmen auf die Programmabarbeitung

37:50.280 --> 37:54.000
in Abhängigkeit davon, was vorher passiert ist, mal das eine, mal das

37:54.000 --> 37:54.320
andere.

37:55.160 --> 37:57.780
Und dafür gibt es typischerweise einen bedingten Sprung.

37:59.060 --> 38:03.980
Und der, den es hier bei der MIMA gibt, heißt JMN, Jump If Negative.

38:05.640 --> 38:09.380
Und da wird nachgeguckt, der Wert, der im Akkumulator steht,

38:10.220 --> 38:15.460
interpretiert als Zweierkomplementdarstellung einer Zahl, ist der

38:15.460 --> 38:16.940
negativ oder nicht.

38:18.280 --> 38:22.060
Und bei Zweierkomplementdarstellung, woran sieht man, ob die Zahl

38:22.060 --> 38:22.820
negativ ist?

38:22.920 --> 38:24.020
Am höchstwertigen Bit.

38:24.120 --> 38:27.380
Wenn das höchstwertige Bit 1 ist, dann ist die Zahl negativ.

38:28.140 --> 38:31.780
Das heißt, was dieser Sprungbefehl tatsächlich macht, er guckt nur

38:31.780 --> 38:36.380
nach, das höchstwertige Bit des Akkumulators, ist das 1 oder 0?

38:37.180 --> 38:40.080
Und deswegen gab es auch vorhin in dem Bild die Rückmeldeleitung vom

38:40.080 --> 38:43.500
höchstwertigen Bit des Akkumulators zum Steuerwerk, damit das jetzt

38:43.500 --> 38:44.720
weiß, was zu tun ist.

38:45.880 --> 38:50.360
Bei der Abarbeitung dieses Maschinenbefehls kommt es nämlich darauf

38:50.360 --> 38:57.020
an, wenn das höchstwertige Bit im Akkumulator eine 1 ist, dann wird

38:57.020 --> 39:00.220
der Sprung ausgeführt, so wie gerade beschrieben, unbedingter Sprung.

39:00.780 --> 39:03.800
Der nächste Befehl kommt von der Stelle, die hier als Adresse

39:03.800 --> 39:04.560
angegeben ist.

39:05.520 --> 39:08.720
Und von da geht es dann normal, in Anführungszeichen, weiter.

39:08.720 --> 39:12.660
Also diese Adresse wird ins Instruktionsadressregister geschoben.

39:13.940 --> 39:19.160
Und wenn das höchstwertige Bit vom Akkumulator eine 0 ist, dann macht

39:19.160 --> 39:21.860
der Maschinenbefehl gar nichts weiter, da wird nicht gesprungen,

39:22.000 --> 39:23.800
sondern es geht halt hinterher mit dem nächsten weiter.

39:24.940 --> 39:27.440
Also Sie können jetzt hier irgendwo hinspringen, wenn der Akkumulator

39:27.440 --> 39:29.480
negativ ist, und ansonsten geht es normal weiter.

39:34.020 --> 39:39.400
Also meinetwegen, Sie laden einen Wert von Speicherstelle 12, Sie

39:39.400 --> 39:42.700
vergleichen den Wert mit dem, der in Speicherstelle 13 steht.

39:43.400 --> 39:45.900
Und bei diesem Equal, erinnern Sie sich?

39:46.080 --> 39:50.660
Ja, hinterher im Akku steht lauter Nullen oder lauter Einsen.

39:51.160 --> 39:54.100
Also insbesondere das höchstwertige Bit ist 0 oder 1.

39:54.860 --> 39:59.360
Und das höchstwertige Bit ist 1, wenn die Werte gleich waren, und 0,

39:59.420 --> 40:00.420
wenn sie ungleich sind.

40:02.400 --> 40:06.000
Und also nach diesem Vergleichsbefehl, das höchstwertige Bit im Akku

40:06.000 --> 40:08.300
ist 1, wenn die Werte gleich sind.

40:10.200 --> 40:13.880
Und das heißt, höchstwertiges Bit 1, wenn Sie jetzt hier so einen

40:13.880 --> 40:17.960
bedingten Sprungbefehl haben, nach Adresse irgendwo, dann wird der

40:17.960 --> 40:22.860
Sprung ausgeführt, wenn da vorne bei dem Vergleich eben rauskam, ja,

40:22.900 --> 40:23.900
die Werte sind gleich.

40:24.720 --> 40:27.520
Und wenn die Werte ungleich sind, dann wird nicht gesprungen, sondern

40:27.520 --> 40:30.640
dann wird einfach der Maschinenbefehl aus der nächsten Speicherstelle

40:30.640 --> 40:30.920
genommen.

40:31.640 --> 40:33.040
Dann geht es hier oben weiter.

40:33.040 --> 40:37.140
Also hier bei Gleichheit springen Sie da unten hin, bei Ungleichheit

40:37.140 --> 40:38.580
machen Sie hier hinten dran weiter.

40:40.860 --> 40:44.060
Das ist die einzige Möglichkeit, jetzt in Abhängigkeit von einem

40:44.060 --> 40:46.020
Ergebnis von vorher, irgendetwas zu tun.

40:47.700 --> 40:55.820
Und hier haben wir jetzt also den Befehl ausgenutzt, der zwei Werte

40:55.820 --> 40:56.400
vergleicht.

40:56.640 --> 41:00.340
Prinzipiell, Sie können immer, egal was vorher war, jetzt springen,

41:00.340 --> 41:03.520
wenn das höchstwertige Bit in Akkumulator 1 ist.

41:04.500 --> 41:07.040
Wenn das nicht durch so einen Vergleichsbefehl kam, dann müssen Sie

41:07.040 --> 41:10.040
vielleicht sonst irgendwie wissen, dass das etwas Sinnvolles

41:10.040 --> 41:10.700
ausdrückt.

41:11.580 --> 41:13.580
Kann ja auch andere Gründe haben.

41:14.500 --> 41:16.640
Meinetwegen, Sie haben was ausgerechnet und Sie wollen jetzt irgendwo

41:16.640 --> 41:20.680
hinspringen, eben wenn das Ergebnis negativ war.

41:22.900 --> 41:25.660
Ach so, und so am Rande, also formal, es gibt auch einen

41:25.660 --> 41:29.920
Maschinenbefehl, der dazu führt, in Anführungszeichen, dass das ganze

41:29.920 --> 41:30.800
Ding stehen bleibt.

41:33.020 --> 41:38.200
Ansonsten würde man sagen, wenn das Programm zu Ende ist und der

41:38.200 --> 41:41.620
Prozessor möchte einen nächsten Befehl, dann ist vielleicht auch

41:41.620 --> 41:42.120
vorbei.

41:43.500 --> 41:47.260
Vielleicht geht auch eine gelbe Warnlampe an, weil da fehlt Programm,

41:47.480 --> 41:47.720
egal.

41:48.700 --> 41:52.960
Also soweit zu den jedenfalls meisten Maschinenbefehlen, die die MIMA

41:52.960 --> 41:53.200
hat.

41:53.600 --> 41:56.180
Es gibt noch zwei weitere, über die ich nicht rede.

41:56.520 --> 42:03.420
Die kriegen Sie dann vielleicht in der technischen Informatik noch

42:03.420 --> 42:03.690
erzählt.

42:06.760 --> 42:08.560
Aber vielleicht auch nicht, weiß ich nicht.

42:09.580 --> 42:14.460
So, und also nochmal, hier ist irgendwie ein Programm mit

42:14.460 --> 42:16.540
Maschinenbefehlen für einen echten Prozessor.

42:17.060 --> 42:20.220
Und da haben Sie zum Beispiel hier unten auch so ein Befehl JMP, das

42:20.220 --> 42:21.480
ist genau dieses Jump.

42:23.160 --> 42:28.300
Und Sie sehen schon, hier stehen auch nirgends Adressen explizit von

42:28.300 --> 42:29.510
aufeinanderfolgenden Speicherstellen.

42:30.460 --> 42:35.500
Jetzt bei Sprungbefehlen braucht man natürlich irgendwie eine Angabe,

42:35.600 --> 42:36.940
wo soll der Sprung hingehen.

42:37.480 --> 42:41.800
Und was man dann häufig macht, ist, also selbst dafür schreibt man da

42:41.800 --> 42:47.300
nicht echte Adressen hin, sondern gibt symbolische Namen an für, das

42:47.300 --> 42:48.580
ist die Stelle, die ich meine.

42:48.580 --> 42:53.360
Also hier springe nach Punkt Groß L3, das sieht man jetzt hier in dem

42:53.360 --> 42:55.980
Ausschnitt nicht, das ist halt weiter oben oder weiter unten.

42:56.820 --> 42:58.400
Genauso hier das Jump L4.

42:59.520 --> 43:02.660
Und hier ein bisschen weiter oben haben Sie übrigens auch diese Zeile

43:02.660 --> 43:06.420
JNE, das ist auch so ein bedingter Sprungbefehl.

43:06.540 --> 43:09.900
Und da wird bedingt nach L2 gesprungen, so ein bisschen nach unten.

43:10.860 --> 43:13.860
Und wahrscheinlich dann hier unten der Sprung zu L3 ist, vielleicht

43:13.860 --> 43:14.880
nach oben, wer weiß.

43:16.240 --> 43:16.720
So.

43:19.440 --> 43:22.620
Also jetzt, wenn wir Ihnen ein Programm hinschreiben, wie zum Beispiel

43:22.620 --> 43:25.700
auf dem nächsten Übungsblatt, dann können Sie die Befehle halt Reihe

43:25.700 --> 43:29.660
nach abarbeiten und sich überlegen, was passiert denn da mit den

43:29.660 --> 43:31.680
Bitmustern, was macht dieses Programm.

43:33.020 --> 43:37.220
Und die zweite Aufgabe auf dem Übungsblatt wird sein, hier ist ein

43:37.220 --> 43:41.080
Programm, aber da fehlen Teile, ergänzen Sie die mal so, dass das und

43:41.080 --> 43:42.160
das und das und das passiert.

43:43.560 --> 43:47.680
Und die dritte Aufgabe wird sein, schreiben Sie mal selber ein

43:47.680 --> 43:52.180
Programm, vollständig, nicht nur Lückentext ausfüllen, sondern ganz

43:52.180 --> 43:54.500
selbstständig, alleine, ohne Vorlage.

43:55.440 --> 43:58.420
Aber machen Sie es nicht zu lang, sonst haben die Tutoren so viel zu

43:58.420 --> 43:58.920
korrigieren.

44:00.740 --> 44:04.040
Also das muss man wirklich sagen, das ist einer der hässlichsten

44:04.040 --> 44:07.160
Aufgabentypen für die Tutoren zum Korrigieren, so Maschinenprogramme.

44:08.140 --> 44:09.180
Das ist ganz eklig.

44:11.300 --> 44:16.640
So, ja, Maschinenbefehle müssen der Reihe nach ausgeführt werden.

44:17.180 --> 44:20.460
Wie macht die CPU das denn, was veranstaltet der Prozessor da?

44:21.880 --> 44:27.720
Und tatsächlich ist das, also bisher so die Vorstellung, ja, ein

44:27.720 --> 44:29.400
Programm besteht aus mehreren Maschinenbefehlen.

44:30.280 --> 44:32.720
Jetzt, wenn man ein bisschen genauer hinguckt, auch bei modernen

44:32.720 --> 44:36.760
Prozessoren ist das so, die Ausführung eines Maschinenbefehls

44:36.760 --> 44:41.380
bedeutet, es wird ein Programm ausgeführt, aus sogenannten

44:41.380 --> 44:42.400
Mikrobefehlen.

44:43.480 --> 44:44.580
Das sind ja sogenannte Mikroprogramme.

44:46.640 --> 44:49.400
Also für jeden Maschinenbefehl, es gibt ein Mikroprogramm.

44:50.560 --> 44:56.380
Und diese Mikroprogramme bei modernen Prozessoren, sie nicht, aber man

44:56.380 --> 44:59.600
kann die auch, nachdem der Prozessor schon im Mainboard drinsteckt,

44:59.720 --> 45:00.800
noch modifizieren.

45:03.420 --> 45:07.220
Aber das sollten wirklich nur die Leute tun, die wissen, wie das Ding

45:07.220 --> 45:07.880
arbeitet.

45:09.000 --> 45:12.100
Und wenn man sich also die Mikroprogramme dann anguckt, für so

45:12.100 --> 45:16.540
Maschinenbefehle, dann stellt man fest, das sind immer die gleichen

45:16.540 --> 45:17.340
drei Teile.

45:17.440 --> 45:22.440
Der erste Teil ist sowieso immer ganz gleich, nämlich die erste Phase

45:22.440 --> 45:25.320
ist, der Maschinenbefehl muss überhaupt erstmal geholt werden aus dem

45:25.320 --> 45:26.120
Hauptspeicher.

45:28.580 --> 45:32.800
Dann die sogenannte Hohlphase, dann gibt es die Dekodierphase, die ist

45:32.800 --> 45:36.780
jetzt bei der MIMA trivial, da muss man nicht viel veranstalten.

45:37.740 --> 45:39.440
Und dann gibt es die Ausführungsphase.

45:40.460 --> 45:45.800
Da passiert halt dann, also die Befehls-Hohlphase, das ist das gleiche

45:45.800 --> 45:48.840
Stück Mikroprogramm für alle Maschinenbefehle, jeder Befehl wird auf

45:48.840 --> 45:50.120
die gleiche Art und Weise geholt.

45:51.680 --> 45:54.220
Aber die Befehls-Ausführungsphase ist natürlich für verschiedene

45:54.220 --> 45:55.480
Maschinenbefehle unterschiedlich.

45:55.640 --> 45:58.160
Bei einer Addition soll was anderes passieren als bei einem Sprung.

46:00.560 --> 46:04.160
Und jeder Teil sind mehr oder weniger lange Mikroprogramme.

46:05.580 --> 46:09.760
Die bestehen aus Mikrobefehlen und ein Mikrobefehl ist dann wirklich

46:09.760 --> 46:14.440
etwas auf so dem Niveau, jetzt, das eine Register soll seinen Wert auf

46:14.440 --> 46:18.640
dem Bus legen und das andere Register da drüben, das soll den Wert,

46:18.740 --> 46:21.640
der jetzt auf dem Bus liegt, lesen und speichern.

46:22.320 --> 46:24.220
Das war dann ein Mikrobefehl.

46:25.300 --> 46:27.240
Oder vielleicht sollen mehrere den Wert lesen.

46:28.320 --> 46:30.960
Und das gucken wir uns jetzt ein bisschen genauer an.

46:35.200 --> 46:38.760
Wobei ich es mir gespart habe, aus Übersichtlichkeitsgründen, da jetzt

46:38.760 --> 46:42.620
auch noch die ganzen roten Steuersignale zu den ganzen Registern

46:42.620 --> 46:45.760
einzumalen, wie dieses Register soll lesen, dieses Register soll

46:45.760 --> 46:48.340
schreiben, da wäre nur noch rote Spaghetti auf dem Bild.

46:49.040 --> 46:50.860
Das muss man sich immer dazu denken.

46:53.200 --> 46:57.780
Aber ansonsten hier, das sind die Register, da ist der Daten- und das,

46:57.780 --> 47:03.420
was passiert hier in Abhängigkeit vielleicht noch von Meldesignalen.

47:04.480 --> 47:11.910
Und da gucken wir uns dann zwei Beispiele an.

47:12.650 --> 47:17.130
Und das erste ist, wie gesagt, für alle Maschinenbefehle gleich, das

47:17.130 --> 47:18.510
ist die Befehls-Holphase.

47:20.070 --> 47:23.530
Da wird, Überraschung, der nächste Befehl aus dem Speicher geholt.

47:24.670 --> 47:28.110
Die Adresse weiß man, die steht im Instruktionsadressregister, also da

47:28.110 --> 47:29.330
muss der Befehl geholt werden.

47:30.110 --> 47:35.210
Und außerdem, was man da auch schon macht, ist, die Adresse vom

47:35.210 --> 47:37.190
nächsten Befehl auszurechnen, also die Adresse im

47:37.190 --> 47:39.410
Instruktionsadressregister um 1 erhöhen.

47:41.570 --> 47:42.770
Also, wie geht das?

47:44.110 --> 47:47.990
Es geht damit los, dass man nur weiß, im Instruktionsadressregister,

47:48.150 --> 47:50.530
da steht die Adresse des nächsten Maschinenbefehls.

47:51.650 --> 47:55.750
Das heißt, im ersten Mikroprogrammschritt kommen die passenden

47:55.750 --> 47:58.870
Steuersignale vom Steuerwerk, die dafür sorgen, dass das

47:58.870 --> 48:02.530
Instruktionsadressregister die Adresse, die es gespeichert hat, auf

48:02.530 --> 48:03.730
den Bus legt.

48:05.650 --> 48:08.710
Adresse sind 20 Bit von den 24, die der Bus bereit ist.

48:09.670 --> 48:12.710
Und es wird dafür gesorgt, ein anderes Steuersignal, dass das

48:12.710 --> 48:16.430
Speicheradressregister den Wert speichert, der auf dem Bus anliegt.

48:17.090 --> 48:20.550
Und das heißt, die Adresse wird kopiert vom Instruktionsadressregister

48:20.550 --> 48:21.870
zum Speicheradressregister.

48:21.870 --> 48:28.130
Die anderen Register lesen den Wert nicht, die speichern den nicht,

48:28.230 --> 48:30.550
denen ist völlig egal, was für eine Adresse da gerade auf dem Bus

48:30.550 --> 48:31.090
rumfliegt.

48:31.790 --> 48:33.550
Die lassen die Finger davon.

48:34.070 --> 48:36.850
Also zum Beispiel der Akkumulator behält seinen alten Wert, da wird

48:36.850 --> 48:39.510
nicht der Wert überschrieben mit der Adresse.

48:40.550 --> 48:44.050
Der kriegt kein Steuersignal, liest etwas und deswegen bleibt der alte

48:44.050 --> 48:44.630
Wert erhalten.

48:44.730 --> 48:45.930
Und genauso die anderen Register.

48:46.710 --> 48:50.730
Also, erster Mikrobefehl, die Adresse zum Speicheradressregister

48:50.730 --> 48:50.970
transportieren.

48:52.190 --> 48:58.310
Nächster Befehl, also Mikrobefehl, diese Adresse, die jetzt im

48:58.870 --> 49:01.250
Speicheradressregister ist, schieben wir nach draußen zum

49:01.690 --> 49:02.010
Hauptspeicher.

49:06.160 --> 49:11.240
Und jetzt nicht nur, also sowohl physikalisch als auch elektrisch,

49:11.640 --> 49:16.660
nicht nur in der MIMA, sondern auch in der Realität, der Speicher ist

49:16.660 --> 49:21.220
sozusagen weit weg vom Prozessor und es dauert tatsächlich eine ganze

49:21.220 --> 49:23.360
Zeit, bis da was zurückkommt.

49:24.420 --> 49:27.960
Also ich habe ja bisher noch gar nicht gesagt, also so ein Prozessor

49:27.960 --> 49:32.180
hat typischerweise so einen Taktgeber, der einmal pro Mikro- oder

49:32.180 --> 49:35.540
Nanosekunde dem Steuerwert sagt, so und jetzt das nächste und jetzt

49:35.540 --> 49:37.580
das nächste und jetzt das nächste.

49:38.240 --> 49:42.820
Aber also das Steuerwerk ist so schnell getaktet, so schnell ist kein

49:42.820 --> 49:46.920
Speicher, der da so extern irgendwo auf dem Mainboard rumfliegt.

49:48.080 --> 49:56.300
Deswegen jetzt im nächsten Schritt immer noch die Adresse liegt an auf

49:56.300 --> 49:59.320
dem Bus nach draußen, damit der Speicher weiß, was man will, aber es

49:59.320 --> 50:02.140
ist noch nichts zurückgekommen, Speicher ist langsam und wir warten

50:02.140 --> 50:03.140
noch einen Takt.

50:03.740 --> 50:08.840
Und dann irgendwann, unterstellen wir mal, jetzt ist es soweit, kommt

50:08.840 --> 50:11.980
was vom Speicher zurück und dann schickt man ein Steuersignal zum

50:12.660 --> 50:16.120
Speicherdatenregister und sagt, jetzt lies mal, was von da oben kommt.

50:17.360 --> 50:20.000
Und das Speicheradressregister, dem sagt man, jetzt schreibt nicht

50:20.000 --> 50:23.500
mehr, jetzt hat der Speicher lang genug die Adresse gesehen.

50:24.120 --> 50:29.680
Da sieht man übrigens noch was, dieses Speicherdatenregister, ach so,

50:29.820 --> 50:33.780
jetzt sieht man es noch nicht, aber Sie werden gleich sehen, das kann

50:33.780 --> 50:36.220
aus zwei Richtungen den Wert kriegen, das ist noch ein bisschen

50:36.220 --> 50:39.760
komplizierter gebaut als die einfachen Bildchen, die ich Ihnen gezeigt

50:39.760 --> 50:40.120
habe.

50:41.300 --> 50:46.940
So, also jetzt endlich, vierter Mikroprogrammschritt, es kommt was aus

50:46.940 --> 50:52.160
dem Speicher zurück, nämlich aus der Speicherstelle, deren Adresse wir

50:52.160 --> 50:54.060
da hingeschickt haben und das war der Inhalt des

50:54.060 --> 50:57.740
Instruktionsadressregisters, das heißt, das, was jetzt hier kommt, ist

50:57.740 --> 50:58.940
der nächste Maschinenbefehl.

51:00.060 --> 51:03.700
Und deswegen im nächsten Mikroprogrammschritt sorgt man dafür, dass

51:03.700 --> 51:06.800
der dann über den Bus transportiert wird zum Instruktionsregister,

51:07.140 --> 51:10.360
damit man ihn gespeichert hat und weiß, aha, das muss jetzt ausgeführt

51:10.360 --> 51:10.880
werden.

51:12.920 --> 51:18.020
Das waren jetzt in diesem Beispiel Prozessor 5 Takte, um den nächsten

51:18.020 --> 51:19.000
Befehl zu holen.

51:20.280 --> 51:23.120
Jetzt ist er da, im Instruktionsregister.

51:26.440 --> 51:27.860
Das ist schon mal ganz schön.

51:28.640 --> 51:32.840
Was man jetzt noch tun muss, immer noch Befehlsholphase, also Befehl

51:32.840 --> 51:35.960
geholt haben wir, aber wir müssen noch die Adresse des nächsten

51:35.960 --> 51:40.360
Maschinenbefehls ausrechnen, der als nächstes dann geladen werden

51:40.360 --> 51:40.360
soll.

51:40.640 --> 51:44.020
Wir sind ja davon ausgegangen, die richtige Adresse steht da immer, da

51:44.020 --> 51:45.500
muss man sie jetzt mal aktualisieren.

51:46.120 --> 51:50.140
Das heißt, man muss eine 1 auf das Instruktionsadressregister drauf

51:50.140 --> 51:50.540
addieren.

51:50.700 --> 51:55.440
Also erster Mikroprofil, wir transportieren diese Adresse ins Register

51:55.440 --> 51:55.840
X.

51:56.780 --> 52:03.020
Das ist ein Register für eine 24-Bit-Adresse, für einen 24-Bit-Wert.

52:03.720 --> 52:07.740
Da kommen jetzt die 20 Bits an von der Adresse und das wird links

52:07.740 --> 52:09.920
aufgefüllt mit vier Nullen, stellen wir uns mal vor.

52:11.660 --> 52:16.400
Im nächsten Schritt, die 1, die wir bequemlichkeitshalber hier in

52:16.400 --> 52:19.600
einem Register haben, wird in Register Y transportiert.

52:20.740 --> 52:24.600
Und bitte, das kann man nicht gleichzeitig tun, also das eine und das

52:24.600 --> 52:27.460
andere, weil man ja über den gemeinsamen Bus geht.

52:27.660 --> 52:29.740
Es können nicht zwei auf den Bus schreiben.

52:30.520 --> 52:31.260
Das geht nicht.

52:31.760 --> 52:34.360
Ich könnte hier so getrennte blaue Pfeile malen, aber das wäre der

52:34.360 --> 52:36.760
gemeinsame Bus, das wäre böse.

52:36.960 --> 52:39.000
Es dürfen nicht zwei gleichzeitig auf den Bus schreiben.

52:39.200 --> 52:40.780
Also die 1 nach Y hinterher.

52:41.980 --> 52:46.480
In X haben wir jetzt schon die Adresse, die alte Adresse des Befehls,

52:46.560 --> 52:47.500
den wir schon geholt haben.

52:47.840 --> 52:49.080
In Y haben wir eine 1.

52:49.400 --> 52:52.040
Im nächsten Schritt kann man jetzt dafür sorgen, dass die beiden

52:52.040 --> 52:55.620
Register X und Y ihre Werte an die Recheneinheit geben und die ist

52:55.620 --> 52:58.560
vielleicht so schnell, dass sie auch gleich den Wert liefert, der in Z

52:58.560 --> 52:59.400
gespeichert wird.

52:59.900 --> 53:02.220
Dann steht jetzt in Z die um 1 größere Adresse.

53:04.520 --> 53:08.760
Und zu guter Letzt, die neue Adresse schieben wir jetzt zurück ins

53:08.760 --> 53:10.200
Instruktionsadressregister.

53:10.420 --> 53:14.480
Also jetzt Z schreibt auf den Bus, Instruktionsadressregister liest

53:14.480 --> 53:15.920
und die anderen machen nichts.

53:16.040 --> 53:18.180
Also die meisten Register machen immer gar nichts an dem Bus.

53:18.740 --> 53:21.200
Schreiben nichts, lesen nichts, ist ihnen alles ganz egal.

53:22.900 --> 53:25.320
Und dann hat man jetzt auch die 1 höhere Adresse im

53:25.320 --> 53:26.780
Instruktionsadressregister.

53:27.540 --> 53:30.120
Das waren jetzt nochmal 4 Mikroprogramm-Schritte.

53:31.540 --> 53:32.620
Da waren wir schon bei 9.

53:33.260 --> 53:37.120
Aber da kann man jetzt tatsächlich mal so ein bisschen was jedenfalls

53:37.120 --> 53:37.900
optimieren.

53:40.020 --> 53:41.880
Und deswegen fassen wir das mal zusammen.

53:42.100 --> 53:46.900
Also wir hatten gerade, das allererste war Instruktionsadressregister

53:46.900 --> 53:51.800
nach Speicheradressregister schieben und dann beim Erhöhen das gleiche

53:51.800 --> 53:53.440
Register nach X transportieren.

53:53.600 --> 53:55.180
Das kann man natürlich auf einmal machen.

53:55.400 --> 53:59.800
Also Instruktionsadressregister, also jetzt ist die Befehlsholphase

54:00.700 --> 54:05.240
wirklich, dass die alte Adresse wird sowohl nach X als auch ins

54:05.240 --> 54:06.980
Speicheradressregister transportiert.

54:07.640 --> 54:07.640
So.

54:08.360 --> 54:12.000
Im nächsten Schritt hinten hier fürs Befehlsholen die Adresse geht zum

54:12.000 --> 54:12.700
Hauptspeicher.

54:13.540 --> 54:16.860
Da wird hier der Datenbus nicht benötigt und deswegen kann man jetzt

54:16.860 --> 54:19.540
während die Adresse zum Speicher geht hier schon mal die 1 nach Y

54:19.540 --> 54:20.480
transportieren.

54:21.180 --> 54:23.540
Und im nächsten Schritt während der Speicher noch braucht

54:23.540 --> 54:26.380
nachzugucken, was steht denn jetzt an dieser Adresse für einen schönen

54:26.380 --> 54:31.180
Wert, kann man hier drin im Rechenwerk schon mal die Adresse um 1

54:31.180 --> 54:31.660
erhöhen.

54:32.420 --> 54:35.260
Im nächsten Schritt, da kommt jetzt hier hinten der neue

54:36.380 --> 54:39.480
Maschinenbefehl zurück, aber gleichzeitig können wir, weil wir den Bus

54:39.480 --> 54:43.620
hier noch nicht brauchen, von da hinten hier vorne die erhöhte Adresse

54:43.620 --> 54:47.880
schon ins Instruktionsadressregister schieben und dann als letztes den

54:47.880 --> 54:49.460
neuen Befehl ins Instruktionsregister.

54:49.640 --> 54:52.740
Dann kann man das überlappen und braucht nur 5 Mikrobefehle statt 9.

54:54.100 --> 54:58.300
Und dann aber wirklich, der Befehl ist im Instruktionsregister und die

54:58.300 --> 55:00.200
Adresse für den nächsten Befehl haben wir schon im

55:00.200 --> 55:01.000
Instruktionsadressregister.

55:02.580 --> 55:04.860
Und dann kann man jetzt anfangen, den Befehl auszuführen.

55:06.260 --> 55:11.600
Und das erste ist, dass das Steuerwerk jetzt von diesem 24 Bit Nexta

55:11.600 --> 55:16.300
Maschinenbefehl, also bei der MIMA, sich einfach nur maximal die

55:16.300 --> 55:18.380
ersten 8 Bits anguckt.

55:19.700 --> 55:22.460
Meistens sind es sogar nur 4 Bits, die legen schon fest, was ist der

55:22.460 --> 55:24.980
nächste Befehl, Load Constant, Load Value.

55:31.640 --> 55:36.640
Also das besorgt sich das Steuerwerk hier, die höchsten Bits vom

55:36.640 --> 55:37.980
Instruktionsregister.

55:38.380 --> 55:40.820
Das ist die Codierung des Maschinenbefehls.

55:41.400 --> 55:46.140
Und was ist denn jetzt das höchstwertige Bit des Akkumulators?

55:46.380 --> 55:48.920
Das braucht man jetzt gleich, falls es ein bedingter Sprung ist und

55:48.920 --> 55:52.420
man wissen muss, springt man nicht, 1 oder 0.

55:53.060 --> 55:55.060
Also da wird jetzt wirklich diese 1 transportiert.

55:57.380 --> 56:01.940
Und dann je nachdem, welches Bitmuster das Steuerwerk sieht, für was

56:01.940 --> 56:06.940
ist der Maschinenbefehl und je nachdem, welches Bit das Steuerwerk

56:06.940 --> 56:11.800
sieht, ist der Akkumulatorinhalt negativ oder nicht, werden jetzt vom

56:11.800 --> 56:16.700
Steuerwerk unterschiedliche Mikroprogramme ausgeführt, für jetzt

56:16.700 --> 56:18.680
wirklich den Maschinenbefehl zu realisieren.

56:20.860 --> 56:25.120
Das ist im Prinzip ganz einfache Hardware, das macht man ganz plump,

56:26.100 --> 56:28.860
aber das lassen wir der technischen Informatik.

56:29.800 --> 56:33.620
Also es wird das alles geholt, vom Steuerwerk gelesen, um zu

56:33.620 --> 56:35.920
entscheiden, was ist denn jetzt wirklich zu tun?

56:36.860 --> 56:39.520
Und das, was dann zu tun ist, hängt vom Maschinenbefehl ab und da

56:39.520 --> 56:42.260
gucken wir uns zwei Beispiele an, die anderen können sich selber

56:42.260 --> 56:42.700
überlegen.

56:43.800 --> 56:48.080
Das eine ist Load Value from Address und das andere ist Sprungbefehl,

56:48.160 --> 56:49.300
unbedingt der Sprungbefehl.

56:51.580 --> 56:55.220
So, Load Value from Address, was muss da getan werden?

56:55.380 --> 57:00.840
Also da steht vorne das Bitmuster für, das ist der Maschinenbefehl,

57:00.980 --> 57:04.460
der jetzt ausgeführt werden soll, das hat das Steuerwerk gesehen und

57:04.460 --> 57:11.340
dahinter in den restlichen 20 Bit steht die Adresse, unter der man im

57:11.340 --> 57:14.980
Hauptspeicher den Wert findet, den man gerne in den Akkumulator laden

57:14.980 --> 57:15.340
möchte.

57:15.640 --> 57:17.540
Ah, das habe ich nicht gesagt, ja, danke.

57:18.020 --> 57:21.300
Die Frage war, ich rede hier von Mikroprogrammen, wo liegen die denn

57:21.300 --> 57:21.560
rum?

57:22.280 --> 57:25.080
Die sind im Steuerwerk und stellen Sie sich vor, die sind da fest

57:25.080 --> 57:28.860
verdrahtet, verlötet, irgendetwas, sind sie nicht ganz, aber...

57:28.860 --> 57:30.900
Also das ist alles im Steuerwerk, ja.

57:33.720 --> 57:37.420
Und da drin gibt es dann ein Mikroprogrammsteuerwerk und so, aber gut.

57:38.040 --> 57:40.640
Also, Load Value from Address.

57:40.760 --> 57:42.200
Was muss man tun?

57:42.380 --> 57:46.440
Also erstens, man muss aus dem Speicher lesen, das heißt, man muss

57:46.440 --> 57:49.040
erst mal die Adresse zum Speicher hintragen und sagen, bitte hier,

57:49.160 --> 57:50.580
dieser Wert, den hätte ich jetzt gerne.

57:51.360 --> 57:55.440
Also erster Mikroprofil, man nimmt die hinteren 20 Bit von dem

57:55.440 --> 58:00.660
Maschinenbefehl, das ist die Adresse, und legt sie auf den Bus, also

58:00.660 --> 58:04.540
das Instruktionsregister schreibt auf den Bus und da hinten das

58:04.540 --> 58:07.900
Speicheradressregister, dem wird gesagt, lies die Adresse, die da

58:07.900 --> 58:08.280
kommt.

58:10.040 --> 58:12.880
Und im nächsten Ding wird wieder die Adresse nach draußen gegeben zum

58:12.880 --> 58:16.800
Hauptspeicher und im nächsten Schritt muss man wieder warten und im

58:16.800 --> 58:19.500
nächsten Schritt kommt dann der Wert vom Hauptspeicher zurück.

58:21.620 --> 58:24.820
Und er kommt dann ins Speicherdatenregister und was ist das jetzt?

58:24.940 --> 58:28.960
Ja, das ist der Wert, den man im Akkumulator haben möchte, ja.

58:30.280 --> 58:33.960
Und deswegen, das letzte ist jetzt Speicherdatenregister, schreibt

58:33.960 --> 58:37.240
diesen Wert auf den Bus und der Akkumulator liest den Wert vom Bus.

58:37.540 --> 58:39.960
Und die anderen Register machen nichts mit dem Bus.

58:41.660 --> 58:45.520
Und dann hat man jetzt unter der Adresse, die hier im Maschinenbefehl

58:45.520 --> 58:49.700
hinten drin stand, aus dem Speicher nachgeguckt, welcher Wert steht da

58:49.700 --> 58:51.480
und den in den Akkumulator transportiert.

58:53.360 --> 58:57.120
Dauerte vier oder fünf Mikroprogrammschritte, kommt halt darauf an,

58:57.160 --> 58:58.260
wie schnell der Hauptspeicher ist.

59:02.180 --> 59:02.320
So.

59:03.180 --> 59:06.740
Anderes Beispiel, Befehlesausführung des Sprungbefehls.

59:08.740 --> 59:09.640
Also was haben wir da?

59:09.720 --> 59:15.700
Da steht also im Instruktionsregister so eine 24-Bit-Folge.

59:15.780 --> 59:19.180
Die vorderen vier Bits sagen, ich bin der unbedingte Sprungbefehl,

59:19.300 --> 59:19.640
Jump.

59:20.080 --> 59:24.520
Und die hinteren 20 Bits sagen, das ist die Adresse, wo es weitergehen

59:24.520 --> 59:26.580
soll mit der Programmausführung.

59:28.600 --> 59:31.460
Und jetzt überlegen Sie mal kurz, was man da veranstalten muss in dem

59:31.460 --> 59:37.760
Prozessor, damit dann der richtige Befehl als nächstes ausgeführt

59:38.100 --> 59:38.460
wird.

59:41.520 --> 59:43.220
Hat jemand einen Vorschlag?

59:44.620 --> 59:44.740
Ja?

59:48.290 --> 59:49.510
Ja, genau.

59:50.250 --> 59:54.990
Also, im Instruktionsregister hinter dem Jump-Befehl steht die 20-Bit,

59:55.070 --> 59:59.710
die Adresse, wo man den nächsten Befehl herholen soll.

01:00:00.450 --> 01:00:04.810
Und wo holt der Prozessor den nächsten Befehl her?

01:00:04.890 --> 01:00:08.150
Na ja, von der Adresse, die im Instruktionsadressregister steht.

01:00:08.610 --> 01:00:12.270
Deswegen, was man tun muss, ist einfach nur diese Adresse ins

01:00:12.270 --> 01:00:14.290
Instruktionsadressregister transportieren.

01:00:16.050 --> 01:00:18.210
Das ist die Ausführung des Sprungbefehls.

01:00:19.330 --> 01:00:21.970
Und dann kommt der nächste Maschinenbefehl, der fängt mit der

01:00:22.690 --> 01:00:23.430
Befehlsholphase an.

01:00:23.470 --> 01:00:25.030
Und was macht die Befehlsholphase?

01:00:25.610 --> 01:00:28.490
Sie erinnern sich, die Adresse, die im Instruktionsadressregister

01:00:28.490 --> 01:00:32.270
steht, das ist jetzt die Zieladresse von dem Sprung eben, wird zum

01:00:32.270 --> 01:00:34.910
Speicher transportiert und da wird der nächste Maschinenbefehl geholt.

01:00:35.050 --> 01:00:36.450
Das ist genau das, was man will.

01:00:36.890 --> 01:00:41.010
Die nächste Befehlsholphase nimmt diese Adresse, die hier angegeben

01:00:41.010 --> 01:00:41.990
war in dem Sprungbefehl.

01:00:42.650 --> 01:00:43.430
Passt genau.

01:00:46.250 --> 01:00:50.930
Und das kann man jetzt dann natürlich für die anderen Maschinenbefehle

01:00:50.930 --> 01:00:51.950
sich auch alles überlegen.

01:00:52.070 --> 01:00:56.630
Das ist zum Teil noch ein bisschen länger, aber das sind die

01:00:56.630 --> 01:00:57.270
wesentlichen Dinge.

01:00:59.470 --> 01:01:07.950
So, und jetzt zum Abschluss noch ein etwas längeres Beispielprogramm.

01:01:10.050 --> 01:01:14.850
So in Anlehnung an das, was wir vorhin hatten, wir initialisieren den

01:01:14.850 --> 01:01:20.050
Akkumulatorinhalt mit 0 und addieren die Werte, die an den Adressen 46

01:01:20.050 --> 01:01:22.370
und 47 und 48 und 49 stehen.

01:01:22.370 --> 01:01:25.350
Das wollen wir jetzt ein bisschen allgemeiner haben.

01:01:29.090 --> 01:01:36.870
Dafür müssen wir also zum Ersten irgendwie festlegen, wo liegen die

01:01:36.870 --> 01:01:39.270
Dinge im Hauptspeicher rum, die wir aufaddieren wollen.

01:01:41.830 --> 01:01:50.330
Und ich möchte nicht die ganze Zeit über Adressen, über Bitfolgen

01:01:50.330 --> 01:01:52.870
reden, deswegen vergebe ich jetzt für alle möglichen Adressen

01:01:52.870 --> 01:01:53.790
symbolische Namen.

01:01:55.450 --> 01:01:59.550
Und wir wollen mal sagen, es gibt eine Adresse im Hauptspeicher, für

01:01:59.550 --> 01:02:00.650
die schreibe ich immer List.

01:02:01.810 --> 01:02:06.790
Und ab der Adresse in einer aufeinanderfolgenden Speicherstellen

01:02:06.790 --> 01:02:10.970
stehen irgendwelche Werte, also meinetwegen hier 11, 22, 33, 44, 55.

01:02:12.150 --> 01:02:16.410
Und das Programm soll so sein, bitte, dass das nicht nur funktioniert,

01:02:16.570 --> 01:02:20.170
um vier oder fünf Werte aufzuaddieren, sondern beliebig viele, also

01:02:20.170 --> 01:02:21.770
solange der Speicher groß genug ist.

01:02:22.610 --> 01:02:28.110
Und deswegen soll es meinetwegen an der Speicherstelle unmittelbar vor

01:02:28.110 --> 01:02:32.670
List, aber geben wir der Stelle mal auch einen symbolischen Namen,

01:02:33.030 --> 01:02:33.870
length.

01:02:34.650 --> 01:02:38.410
Es soll eine Speicherstelle geben, da steht drin, wie viele Werte

01:02:38.410 --> 01:02:41.570
sollen denn überhaupt aufaddiert werden, wie lang ist dieser Vektor,

01:02:41.630 --> 01:02:42.590
wie lang ist diese Liste.

01:02:43.370 --> 01:02:45.870
Also die sollte dann bitte mit 5 initialisiert sein.

01:02:46.810 --> 01:02:49.970
Also irgendwo steht eine Zahl 5, an irgendeiner Adresse stehen

01:02:49.970 --> 01:02:53.110
hintereinander weg 5 Werte, also so viele wie hier vorher

01:02:53.110 --> 01:02:53.950
abgespeichert sind.

01:02:55.270 --> 01:03:00.630
Und dann brauchen wir noch drei Variablen, also das, was Sie in Java

01:03:00.630 --> 01:03:03.210
als lokale Variablen oder so schon gesehen haben.

01:03:03.870 --> 01:03:07.670
Da wir nur einen Akkumulator intern haben, das muss also auch alles

01:03:07.670 --> 01:03:09.150
irgendwie im Hauptspeicher rumliegen.

01:03:09.750 --> 01:03:14.970
Für die vergebe ich also auch nochmal drei symbolische Namen, cnt für

01:03:14.970 --> 01:03:18.630
count, da werden wir zählen, wie viele haben wir denn schon

01:03:18.630 --> 01:03:19.130
aufaddiert.

01:03:21.590 --> 01:03:27.950
Eine Stelle mit Adresse sum, da soll am Ende die Summe stehen, also am

01:03:27.950 --> 01:03:28.890
Ende die Summe aller.

01:03:29.590 --> 01:03:36.030
Und eine Speicherstelle, die heißt ref und Sie werden sehen, da steht

01:03:36.030 --> 01:03:41.030
kein Wert, den wir irgendwie aufaddiert haben oder so, sondern eine

01:03:41.030 --> 01:03:41.470
Adresse.

01:03:43.770 --> 01:03:53.150
Also das Ziel ist, dass in so einer Situation nach Ausführung des

01:03:53.150 --> 01:03:58.070
ganzen Programmes an der Speicherstelle, die hier sum heißt, steht die

01:03:58.070 --> 01:04:04.030
Summe, also alles Modulo 2 hoch 24 und zweier Komplementdarstellung

01:04:04.030 --> 01:04:10.810
und so, die Summe aller Werte, die Sie finden an den Speicherstellen,

01:04:11.850 --> 01:04:15.170
die man vielleicht auch symbolisch als List in eckigen Klammern 0,

01:04:15.270 --> 01:04:19.310
List eckige Klammer 1, List 2, List 3, List 4 bezeichnen könnte.

01:04:19.550 --> 01:04:20.990
Hatten Sie schon Arrays in Java?

01:04:22.070 --> 01:04:25.270
Nein, also gut, es heißt einfach so.

01:04:27.890 --> 01:04:33.770
Also die Werte an diesen Speicherstellen, die sollen alle aufaddiert

01:04:33.770 --> 01:04:37.650
werden und zwar es sollen so viele aufaddiert werden, wie der Inhalt

01:04:37.650 --> 01:04:40.150
der Speicherstelle mit dem Namen length sagt.

01:04:41.410 --> 01:04:42.190
Das ist der Plan.

01:04:45.440 --> 01:04:49.460
Okay, also fangen wir an und ich habe es vorhin schon gesagt, wann

01:04:49.460 --> 01:04:55.180
immer Sie programmieren, egal was, initialisieren Sie alle Werte, die

01:04:55.180 --> 01:04:57.100
Sie initialisieren müssen, alle.

01:05:00.880 --> 01:05:04.520
Und das kann auch sozusagen beliebig teuer sein, Sie müssen es ja nur

01:05:04.520 --> 01:05:08.100
einmal am Anfang machen, ob Sie da jetzt eine Mikrosekunde mehr oder

01:05:08.100 --> 01:05:10.860
weniger brauchen, ist wirklich ganz egal für Ihr Programm.

01:05:12.040 --> 01:05:15.880
Da können Sie nicht groß Zeit sparen, da können Sie auch nicht groß

01:05:15.880 --> 01:05:19.160
Bytes sparen beim Speicherplatz, Programmgröße, irgendwas.

01:05:19.760 --> 01:05:23.640
Vergessen Sie es, initialisieren Sie Ihre Variablen, sonst ist es im

01:05:23.640 --> 01:05:25.740
Allgemeinen manchmal einfach falsch.

01:05:27.280 --> 01:05:29.000
Also initialisieren wir.

01:05:30.460 --> 01:05:36.040
Wir laden die Konstante 0 in den Akkumulator, load constant 0, store

01:05:36.040 --> 01:05:39.760
value an der Adresse sum, das heißt sum initialisieren wir mit 0.

01:05:42.980 --> 01:05:48.060
Das macht den Wert 0 an diese Stelle explizit, im Akkumulator steht

01:05:48.060 --> 01:05:50.540
die 0 immer noch, das heißt wir können das auch jetzt gleich noch an

01:05:50.540 --> 01:05:52.020
einer anderen Stelle speichern.

01:05:53.460 --> 01:05:56.500
Ich sage mal einfach variable count.

01:06:01.880 --> 01:06:08.500
Dann steht da ldc list, das heißt wir laden jetzt einen Wert, eine

01:06:08.500 --> 01:06:13.920
Konstante in den Akkumulator und wir stellen uns vor, dass wir hier

01:06:13.920 --> 01:06:18.520
die Adresse hinschreiben, Adresse, eine Adresse tun wir in den

01:06:18.520 --> 01:06:22.700
Akkumulator, nämlich die Adresse des ersten Wertes von unserer Liste

01:06:22.700 --> 01:06:23.440
von Werten.

01:06:24.700 --> 01:06:28.200
Also wir stellen uns hier vor, diese Adresse wird in den Akkumulator

01:06:28.200 --> 01:06:34.120
geladen und jetzt steht die Adresse da und jetzt speichern wir diese

01:06:34.120 --> 01:06:37.220
Adresse in der Variablen ref.

01:06:39.240 --> 01:06:43.680
Also diese Variable speichert nicht irgendeinen Wert, sondern eine

01:06:43.680 --> 01:06:44.120
Adresse.

01:06:46.820 --> 01:06:47.380
Gut.

01:06:49.260 --> 01:06:52.520
Und wir stellen uns vor, die Liste ist vernünftig initialisiert, also

01:06:52.520 --> 01:06:53.600
da tun wir nichts.

01:06:54.200 --> 01:06:57.780
Das Programm soll funktionieren, egal was da vernünftig initialisiert

01:06:57.780 --> 01:06:58.060
steht.

01:06:59.900 --> 01:07:04.360
Und jetzt kommt das Programm und das Programm soll ja funktionieren,

01:07:04.640 --> 01:07:07.660
bitte unabhängig davon, wie viele Werte wir aufaddieren.

01:07:08.240 --> 01:07:11.800
Und wir möchten immer das gleiche Programm, gleicher Länge,

01:07:12.320 --> 01:07:16.740
syntaktisch, das Programm, der Programmtext soll immer gleich bleiben

01:07:16.740 --> 01:07:19.960
und es soll funktionieren für unterschiedlich viele aufzuaddierende

01:07:19.960 --> 01:07:20.320
Werte.

01:07:21.000 --> 01:07:26.240
Das heißt, da muss man irgendwo mal zurückspringen, sonst, also wenn

01:07:26.240 --> 01:07:28.420
man mehr Werte addieren wollte, müsste man ja immer mehr

01:07:28.420 --> 01:07:30.200
Additionsbefehle da stehen haben.

01:07:31.420 --> 01:07:31.620
So.

01:07:34.040 --> 01:07:39.460
Und jetzt sehen Sie schon da oben, also der erste Maschinenbefehl ist

01:07:39.460 --> 01:07:41.820
so ein Load Indirect Value.

01:07:44.000 --> 01:07:47.680
Und das ist auch eine Stelle im Programm, da habe ich jetzt einen

01:07:47.680 --> 01:07:49.360
symbolischen Namen gegeben, Next.

01:07:49.460 --> 01:07:51.660
Das ist also eine Adresse im Programmspeicher.

01:07:52.660 --> 01:07:55.960
Und da habe ich einen Namen gegeben, weil es nämlich hier unten einen

01:07:55.960 --> 01:07:57.700
unbedingten Sprungbefehl gibt.

01:07:58.140 --> 01:08:00.100
Hier der vorletzte, ja, Jump Next.

01:08:00.660 --> 01:08:05.020
Wenn da die Programmausführung hier unten hinkommt, dann wird da

01:08:05.020 --> 01:08:07.840
hochgesprungen, dann wird es wieder von vorne ausgeführt, ja.

01:08:09.780 --> 01:08:16.600
Und also vom vorletzten Befehl springt man immer nach oben, das heißt,

01:08:16.700 --> 01:08:20.700
wenn man hier hinten zu diesem Haltbefehl kommt, zu dem allerletzten

01:08:20.700 --> 01:08:21.620
Wir sind fertig.

01:08:22.940 --> 01:08:26.120
Diesen Befehl habe ich auch der Adresse in symbolischen Namen gegeben,

01:08:26.220 --> 01:08:28.880
da wird von woanders hingesprungen und das ist hier die drittletzte

01:08:28.880 --> 01:08:32.360
Zeile, da ist so ein bedingter Sprungbefehl, ja, Jump if negative,

01:08:32.880 --> 01:08:34.160
dann wir sind fertig.

01:08:35.080 --> 01:08:37.220
So, das ist die grobe Struktur erstmal, ja.

01:08:38.160 --> 01:08:40.860
Und jetzt gucken wir uns an, was passiert hier.

01:08:41.380 --> 01:08:52.220
Also, es geht los mit load indirect value ref und ref ist eine Adresse

01:08:52.220 --> 01:08:53.420
im Hauptspeicher.

01:08:55.580 --> 01:08:58.480
Und bei load indirect value, was wird gemacht?

01:08:58.640 --> 01:09:01.920
Es wird diese Adresse genommen im Hauptspeicher, es wird geguckt,

01:09:02.040 --> 01:09:06.260
welcher Wert steht da, das ist hier der von dem ersten Element der

01:09:06.260 --> 01:09:10.780
Liste und dieser Wert, der da steht, der wird nochmal als Adresse

01:09:10.780 --> 01:09:13.000
genommen, ja, indirekt.

01:09:13.620 --> 01:09:17.120
Und es wird dann im Hauptspeicher unter dieser Adresse nachgeguckt und

01:09:17.120 --> 01:09:21.720
der Wert, der da steht, das ist die 11, die wird in den Akkumulator

01:09:21.720 --> 01:09:22.200
geholt.

01:09:22.840 --> 01:09:26.480
Das ist das, was load indirect value ref macht.

01:09:27.680 --> 01:09:31.980
Wenn da im Hauptspeicher unter dieser Adresse die Adresse von der 11

01:09:31.980 --> 01:09:33.520
steht, dann landet die 11 im Akku.

01:09:36.510 --> 01:09:40.010
Das ist also ein Wert, ein Listenelement, das wir geholt haben.

01:09:40.990 --> 01:09:47.230
Da addieren wir jetzt drauf die Summe aller Werte, die wir bisher

01:09:47.230 --> 01:09:50.530
schon ausgerechnet hatten, das ist aber 0, wir hatten noch gar nichts

01:09:50.530 --> 01:09:53.590
aufaddiert, da bleibt der Wert natürlich bei 11.

01:09:54.010 --> 01:09:56.850
Und dann haben wir einen neuen Wert und den speichern wir jetzt in der

01:09:56.850 --> 01:09:59.290
Variable Summe und dann steht die 11 da.

01:09:59.550 --> 01:10:01.990
Dann haben wir den ersten Wert sozusagen aufaddiert auf die 0.

01:10:04.590 --> 01:10:06.650
Das ist schon mal ein Teil der Aufgabe.

01:10:10.240 --> 01:10:14.280
Jetzt wollen wir uns gerne noch merken, dass wir ein Element

01:10:14.280 --> 01:10:17.280
aufaddiert haben, das heißt, wir wollen diese Variable Count um 1

01:10:17.280 --> 01:10:17.800
erhöhen.

01:10:18.640 --> 01:10:23.920
Da holen wir die 1, die konstante 1 in den Akkumulator, addieren die

01:10:23.920 --> 01:10:29.340
bisherige Anzahl, den bisherigen Wert von Count, das ist 1 und

01:10:29.340 --> 01:10:32.340
speichern uns den neuen Wert, der jetzt 1 größer ist, bei Count ab,

01:10:32.400 --> 01:10:33.260
dann steht da die 1.

01:10:34.660 --> 01:10:38.680
Und jetzt wissen wir, wir haben so viele Werte aufaddiert, wie in

01:10:38.680 --> 01:10:40.000
dieser Variable Count steht.

01:10:40.420 --> 01:10:42.060
Das ist jetzt richtig so.

01:10:45.520 --> 01:10:50.660
Und jetzt kommt die Vorbereitung für das möglicherweise nächste

01:10:50.660 --> 01:10:53.780
Listenelement, das wir von einer anderen Adresse holen müssen.

01:10:53.780 --> 01:10:57.500
Das holen wir jetzt nicht mehr von da, wo das erste Listenelement

01:10:57.500 --> 01:10:59.060
steht, sondern eins dahinter.

01:10:59.980 --> 01:11:03.580
Das heißt, jetzt in dieser Variable Ref, wo die Adresse des nächsten

01:11:03.580 --> 01:11:05.880
Elements steht, das wir aufaddieren wollen, müssen wir jetzt eins

01:11:05.880 --> 01:11:06.560
draufaddieren.

01:11:07.120 --> 01:11:11.520
Also wieder, wir holen die 1 in den Akkumulator, addieren den Inhalt

01:11:11.520 --> 01:11:15.180
der Speicherstelle Ref, das ist eine Adresse, da haben wir jetzt eine

01:11:15.180 --> 01:11:16.320
1 größere Adresse.

01:11:17.120 --> 01:11:19.280
Und das ist dann also nicht mehr sozusagen die Adresse von

01:11:19.280 --> 01:11:22.080
Listenelement 0, sondern die von Listenelement 1.

01:11:23.540 --> 01:11:27.120
Und diesen Wert, den speichern wir in unserer Variable Ref, die uns

01:11:27.120 --> 01:11:30.340
sagt, wo kriegen wir den nächsten Wert her fürs Aufaddieren.

01:11:33.180 --> 01:11:34.940
Falls es einen nächsten Wert gibt.

01:11:35.660 --> 01:11:38.460
Und dann müssen wir jetzt noch gucken, müssen noch mehr Werte

01:11:38.460 --> 01:11:40.760
aufaddiert werden oder war es das?

01:11:41.640 --> 01:11:43.120
Und dafür, wie macht man das?

01:11:43.200 --> 01:11:46.020
Man muss vergleichen, in Count steht, wie viele Werte haben wir schon

01:11:46.020 --> 01:11:46.700
aufaddiert.

01:11:47.820 --> 01:11:51.140
In Length steht, wie viele Werte müssen wir aufaddieren.

01:11:52.160 --> 01:11:54.280
Man muss mal jetzt nachgucken, sind die beiden Werte gleich oder

01:11:54.280 --> 01:11:54.600
nicht.

01:11:56.560 --> 01:12:01.280
Also, meinetwegen, wir laden den Wert aus Count, das ist also hier die

01:12:01.280 --> 01:12:03.460
1, in den Akkumulator.

01:12:04.400 --> 01:12:08.200
Und dann benutzen wir den Maschinenbefehl Equal, vergleiche mit dem

01:12:08.200 --> 01:12:12.300
Inhalt der Speicherstelle mit Adresse Length, das ist die 5.

01:12:12.900 --> 01:12:18.320
Vorher stand da 1 im Akku, 5 ist anders, ist nicht gleich, deswegen im

01:12:18.320 --> 01:12:19.860
Akku landen lauter Nullen.

01:12:21.660 --> 01:12:26.080
Und die Null bedeutet, die Werte waren ungleich und das heißt, wir

01:12:26.080 --> 01:12:27.460
haben noch nicht alles aufaddiert.

01:12:29.420 --> 01:12:32.180
Und deswegen müssen wir dann wieder nach oben.

01:12:32.880 --> 01:12:37.140
Und nur wenn wir festgestellt hätten, die Werte sind gleich, dann

01:12:37.140 --> 01:12:38.820
wüssten wir, alle sind fertig.

01:12:38.820 --> 01:12:44.060
Und wenn die Werte gleich wären, dann wäre jetzt im Akku eine Minus 1,

01:12:44.200 --> 01:12:47.820
also alle Bits auf 1 gesetzt, der Wert wäre negativ.

01:12:48.220 --> 01:12:52.820
Und deswegen, wenn wir jetzt bedingt zu dann springen, dann sind wir

01:12:52.820 --> 01:12:56.600
wirklich fertig, weil dann im Akku vorne eine 1 Stunde, wenn der

01:12:56.600 --> 01:13:01.040
Vergleich gleich gewesen wäre, Count gleich Length, ist aber hier

01:13:01.040 --> 01:13:01.680
nicht der Fall.

01:13:01.840 --> 01:13:05.120
Im Akku steht 0, deswegen wird dieser bedingte Sprung nicht

01:13:05.120 --> 01:13:05.840
ausgeführt.

01:13:06.900 --> 01:13:07.660
Und was passiert?

01:13:07.660 --> 01:13:10.840
Es wird der unbedingte Sprung ausgeführt, wir springen dann nach oben

01:13:10.840 --> 01:13:11.340
zunächst.

01:13:12.480 --> 01:13:18.600
Und es geht weiter mit Load Indirect von REF, also wir gucken bei REF

01:13:18.600 --> 01:13:22.500
nach, welche Adresse steht da, die von List 1, welcher Wert ist da im

01:13:22.500 --> 01:13:24.340
Speicher und den holen wir in den Akkumulator.

01:13:25.240 --> 01:13:30.760
Addieren da drauf die bisherige Summe, 11 gibt 33, speichern das als

01:13:30.760 --> 01:13:36.440
neue Summe in der entsprechenden Speicherstelle ab, holen eine 1,

01:13:36.600 --> 01:13:43.380
erhöhen die Variable Count um 1, dann ist das 2, besorgen uns die

01:13:43.380 --> 01:13:46.760
Adresse des nächsten Listen-Elementes, also nehmen die Konstante 1,

01:13:46.860 --> 01:13:49.980
addieren die bisherige Adresse drauf, dann haben wir die vom dritten

01:13:49.980 --> 01:13:52.040
Element und speichern uns die in REF.

01:13:53.120 --> 01:13:58.060
Und dann wieder gucken wir, haben wir jetzt alle aufaddiert, 2 gleich

01:13:58.060 --> 01:14:00.500
5, also Count gleich Length oder nicht.

01:14:01.260 --> 01:14:07.260
Dann wird 2 verglichen mit 5, das ist nicht gleich, es kommt nicht

01:14:07.260 --> 01:14:11.840
Minus 1 raus, man springt nicht ans Ende und deswegen unbedingt der

01:14:11.840 --> 01:14:12.940
Sprung wieder nach oben.

01:14:13.580 --> 01:14:20.760
Und es geht weiter, das dritte Element wird geholt, 33, die bisherige

01:14:20.760 --> 01:14:26.460
Summe, auch 33 wird draufaddiert, gibt 66, wird abgespeichert, der

01:14:26.460 --> 01:14:30.980
Zähler um 1 erhöht auf 3, die Adresse um 1 erhöht, es wird wieder

01:14:30.980 --> 01:14:34.560
geguckt, sind wir jetzt fertig, nein, 4 ist immer noch nicht gleich 5,

01:14:34.700 --> 01:14:35.780
nochmal von vorne.

01:14:36.680 --> 01:14:43.480
Und dann irgendwann hat man alle 5 aufaddiert, in der Summe steht 165,

01:14:44.220 --> 01:14:48.180
bei Count steht 5 und wenn man dann Count und Length vergleicht,

01:14:48.300 --> 01:14:52.480
stellt man fest, ja, die sind gleich, das Bitmuster im Akku ist alles

01:14:52.480 --> 01:14:57.360
1, also die Minus 1, wenn Sie das Zweierkomplement nehmen und dieser

01:14:57.360 --> 01:15:03.400
bedingte Sprung, Jump if negative, wird ausgeführt und Sie sind bei

01:15:03.400 --> 01:15:05.120
Halt und alles ist fertig.

01:15:07.940 --> 01:15:11.700
Also der wesentliche Punkt hier ist, also erstens, man hat eine

01:15:11.700 --> 01:15:13.580
Schleife, benutzt das gleiche Programmstück immer wieder.

01:15:15.780 --> 01:15:20.240
Zweitens, wir haben hier ausgenutzt, dass wir also erstens im Speicher

01:15:20.240 --> 01:15:24.320
an einer Stelle eine Adresse als Wert stehen hatten, um Load Indirect

01:15:24.320 --> 01:15:25.640
Value machen zu können.

01:15:31.000 --> 01:15:35.140
Und indem man also diese Adresse sorgfältig weiterschaltet, so wie es

01:15:35.140 --> 01:15:39.420
intern die CPU auch immer macht, im Normalfall

01:15:39.420 --> 01:15:42.620
Instruktionsadressregister 1 erhöhen, das haben wir hier auch benutzt.

01:15:43.980 --> 01:15:46.960
Und dann hat man alles aufaddiert.

01:15:48.060 --> 01:15:52.660
Sie können ja noch mal darüber nachdenken, also vor allem vielleicht

01:15:52.660 --> 01:15:56.660
über Arithmetik, also einfach zwei Werte mit Zweierkomplement und so.

01:15:57.000 --> 01:16:00.260
Es kann natürlich passieren, dass hier die Werte beim Aufaddieren

01:16:00.260 --> 01:16:03.640
prinzipiell bei Addition, kann ein Wert rauskommen, den können Sie gar

01:16:03.640 --> 01:16:05.800
nicht mehr in 24 Bit vernünftig darstellen.

01:16:07.800 --> 01:16:11.260
Dann wird halt Modulo gerechnet und das Ergebnis auch wieder

01:16:11.260 --> 01:16:12.240
Zweierkomplement.

01:16:13.120 --> 01:16:17.940
So und damit sind wir tatsächlich fertig mit dieser einfachen Variante

01:16:17.940 --> 01:16:18.580
von MIMA.

01:16:19.660 --> 01:16:23.020
Also grob, na ja, jetzt warten Sie die 30 Sekunden vielleicht auch

01:16:23.020 --> 01:16:24.000
noch, bevor sie wegrennen.

01:16:25.840 --> 01:16:29.000
Also grob, was Sie typischerweise in jedem Prozessor haben, ist so ein

01:16:29.000 --> 01:16:33.320
Steuerwerk, so ein Rechenwerk und so ein Speicherwerk und vielleicht

01:16:33.320 --> 01:16:34.220
noch andere Dinge.

01:16:36.040 --> 01:16:40.840
Und es werden einzelne Maschinenbefehle ausgeführt und de facto

01:16:40.840 --> 01:16:44.740
tatsächlich Ausführung eines Maschinenbefehls heißt, eine Folge von

01:16:44.740 --> 01:16:50.580
einem Mikroprogramm wird ausgeführt und in den Hausaufgaben dürfen Sie

01:16:50.580 --> 01:16:52.680
sich dann selber mal an sowas versuchen.

01:16:53.000 --> 01:16:53.720
Dankeschön.

