WEBVTT

00:08.480 --> 00:12.260
Also, ich begrüße euch herzlich zur ersten Übung der Technischen

00:12.260 --> 00:13.300
Informatik II.

00:14.100 --> 00:19.280
Nachdem wir die organisatorischen Sachen, die Übungen bzw.

00:19.760 --> 00:23.820
Vorlesungsbetrieb hier betreffen, geklärt haben, möchten wir auf den

00:23.820 --> 00:24.760
Stoff eingehen.

00:25.740 --> 00:32.080
Und ich werde mal versuchen, euch heute einen Überblick zu geben,

00:32.080 --> 00:39.100
anhand von Aufgaben über das Feld, in dem sich die Technische

00:39.100 --> 00:42.780
Informatik II im Sommersemester bewegen wird.

00:43.460 --> 00:47.820
Wir haben gestern in der Vorlesung angefangen, oder wir haben die

00:47.820 --> 00:51.800
Anforderungen höherer Programmiersprachen an die Hardware, an

00:51.800 --> 00:55.280
Rechnerstrukturen behandelt.

00:55.280 --> 01:00.220
Und wir haben hierzu die Programmiersprache C als höhere

01:00.220 --> 01:02.480
Programmiersprache kurz eingeführt.

01:04.300 --> 01:09.760
Unser Ziel ist es nicht, dass man euch hier die C beibringt.

01:10.480 --> 01:13.560
Ich weiß nicht, vielleicht können einige von euch in C programmieren.

01:14.000 --> 01:24.860
Aber diese in C geschriebenen Programmi laufen ja auf alle Hardware

01:24.860 --> 01:29.600
-Systeme, also Mikrorechner-Systeme, die vorhanden sind.

01:30.440 --> 01:37.400
Die Technische Informatik II wird euch hier die Informationen oder das

01:37.400 --> 01:42.740
Wissen vermitteln, wie ist es überhaupt möglich, dass Programmi, die

01:42.740 --> 01:47.300
in einer höheren Programmiersprache wie C, das kann natürlich auch

01:47.300 --> 01:52.140
Java oder C++ sein, auf die Hardware abgebildet werden.

01:53.880 --> 02:00.200
Für uns in der Technischen Informatik II sind die zwei Ebenen hier,

02:00.420 --> 02:05.600
die rot und grün markiert sind, in der Hierarchie eines Rechner

02:05.600 --> 02:07.300
-Systems sehr interessant.

02:08.300 --> 02:11.700
Wir haben in der Technischen Informatik I die digitale Ebene

02:11.700 --> 02:12.400
behandelt.

02:13.160 --> 02:17.920
Und wir haben gesehen, dass wir dort logische bzw.

02:18.260 --> 02:22.660
arithmetische Funktionen, also eigentlich Algorithmen zur Berechnung

02:22.660 --> 02:27.860
von logischen und arithmetischen Funktionen, auf die Hardware

02:27.860 --> 02:28.600
abbilden.

02:28.600 --> 02:34.460
Als letztes, wenn ihr euch erinnert, haben wir die Register-Transfer

02:34.460 --> 02:39.360
-Ebene behandelt und wir haben die Programmabläufe zur Realisierung

02:39.360 --> 02:44.140
von Additionswerken, von Multiplikationswerken in Form von Register

02:44.140 --> 02:46.440
-Transfer -Anweisungen beschrieben.

02:46.440 --> 02:59.960
Das heißt, eine Zuweisung des Wertes eines Registers mit dem Ergebnis

02:59.960 --> 03:01.720
einer arithmetischen bzw.

03:02.120 --> 03:03.580
logischen Berechnung.

03:03.960 --> 03:08.560
Hier in dem Fall die Unverknüpfung zwischen zwei Teilen, also einem

03:08.560 --> 03:13.260
Registerinhalt und noch einem Operand und das Ergebnis soll wiederum

03:13.260 --> 03:14.260
irgendwo landen.

03:15.260 --> 03:23.720
In C wissen wir aus der Vorlesung gestern, dass wir dort natürlich

03:23.720 --> 03:28.100
alle Hilfsmittel, alle Elemente einer höheren Programmiersprache zur

03:28.100 --> 03:29.000
Verfügung haben.

03:29.660 --> 03:36.060
Variablen, Funktionen, Zeiger und Arrays, Kontrollstrukturen, die man

03:36.060 --> 03:41.620
braucht zur Implementierung von Algorithmen.

03:42.340 --> 03:50.140
Und wir werden sehen im Laufe des Semesters, wie diese Algorithmen auf

03:50.140 --> 03:53.340
eine bestimmte Hardware abgebildet werden können.

03:54.280 --> 03:57.520
Und dazu betrachten wir diese zwei Ebenen.

03:57.680 --> 04:04.000
Einmal die Ebene der Assembler-Sprache und einmal die Ebene der

04:04.000 --> 04:05.100
Maschinensprache.

04:05.100 --> 04:10.780
Das heißt die Ebene, in der die Programmi und ihre Daten in einer Form

04:10.780 --> 04:13.400
vorliegen, die vom Prozessor bzw.

04:13.600 --> 04:16.660
vom Mikrorechner direkt interpretiert werden können.

04:18.360 --> 04:26.080
Thema der heutigen Übung ist eigentlich, wie wir jetzt, oder ich

04:26.080 --> 04:32.900
möchte kurz erläutern, welchen Zusammenhang jetzt hier zwischen dieser

04:32.900 --> 04:36.640
digitalen Ebene und der Maschinensprache-Ebene existiert.

04:37.440 --> 04:43.540
Beziehungsweise, wie kommt man von einem Programm, was in C

04:43.540 --> 04:45.400
geschrieben ist bzw.

04:45.680 --> 04:50.520
was in Assembler vorgegeben ist, auf diese Maschinendarstellung, die

04:50.520 --> 04:53.020
für den Prozessor direkt interpretierbar ist.

04:54.380 --> 04:57.760
Das Ganze will ich anhand von Aufgaben hier behandeln.

04:58.500 --> 05:04.120
Und zwar, in der ersten Aufgabe geht es darum, ein Algorithmus für

05:04.120 --> 05:04.780
eine...

05:06.340 --> 05:08.200
Ja, da fehlt eine Folie.

05:23.960 --> 05:31.880
In der ersten Aufgabe geht es darum, eine euch bekannte Funktion, das

05:31.880 --> 05:36.560
ist die logische Funktion, die Antivalenz zu implementieren und mit

05:36.560 --> 05:40.520
Hilfe von einem sehr einfachen Rechenwerk, wir nennen mal das

05:40.520 --> 05:45.200
Rechenwerk, das heißt eine Einheit, die arithmetische und logische

05:45.200 --> 05:47.200
Operationen ausführen kann.

05:47.760 --> 05:51.280
Haben wir am Ende der Vorlesung Technische Informatik 1 kennengelernt,

05:51.400 --> 05:52.280
also eine ALU.

05:53.320 --> 05:59.020
Der Datenfluss hier in diesem einfachen Rechenwerk enthält lediglich

05:59.020 --> 06:00.800
ein NAND-Gatter.

06:02.160 --> 06:07.140
Das heißt, um jetzt diese Antivalenzfunktion, der Rest, was man hier

06:07.140 --> 06:12.080
sieht, das sind Speicherbausteine, also lese ich, schreibe ich

06:12.080 --> 06:18.580
Speicherbausteine, RAM hier, wo man vier Werte hier mit den zwei

06:18.580 --> 06:24.420
Adressleitungen A0 und A1, kann man vier Plätze praktisch in diesem

06:24.420 --> 06:26.920
RAM -Baustein hier adressieren.

06:26.920 --> 06:30.740
Das sind Multiplexer bzw.

06:31.280 --> 06:37.580
Demultiplexer, die nur dazu vorhanden sind, um den Datenfluss, um die

06:37.580 --> 06:42.400
Steuerung des Datenflusses durch dieses Schaltwerkes oder durch diese

06:42.400 --> 06:45.520
Schaltung zu garantieren.

06:46.760 --> 06:51.180
Für die Informationswerte ist es so, damit Sie die Aufgabe hier mal

06:51.180 --> 06:57.900
verstehen, die Funktion von einem Multiplexer sollte man so

06:57.900 --> 07:06.780
vorstellen, dass man hier einen Baustein hat mit zwei Eingängen, die

07:06.780 --> 07:11.360
mit 0 und 1 hier markiert sind oder gekennzeichnet sind und einem

07:11.360 --> 07:12.560
einzigen Ausgang.

07:13.560 --> 07:19.580
Weiterhin existiert ein sogenannter Steuereingang und in Abhängigkeit

07:19.580 --> 07:25.460
von den Werten, die an diesem Steuereingang anliegen, wird entweder

07:25.460 --> 07:27.200
der 0.

07:27.280 --> 07:31.760
Eingang auf den Ausgang durchgeschaltet oder der 1.

07:31.920 --> 07:33.800
Eingang auf den Ausgang durchgeschaltet.

07:33.800 --> 07:41.400
Das heißt in dem Fall hier, wenn es 3 gleich 0 ist, dann wird alles,

07:41.600 --> 07:46.820
was an dieser Leitung hier anliegt, auf den Ausgang durchgeschaltet.

07:47.320 --> 07:53.480
Wenn es 3 gleich 1 ist, dann wird das, was hier anliegt, auf den

07:53.480 --> 07:55.160
Ausgang durchgeschaltet.

07:55.320 --> 07:58.020
Der andere Eingang ist praktisch verregelt.

07:59.020 --> 08:05.500
Der Multiplexer realisiert die Umkehrung der Funktionalität von diesem

08:05.500 --> 08:06.300
Multiplexer.

08:06.860 --> 08:11.320
Das heißt, er hat zwei Ausgänge, wie man hier sieht, einen einzigen

08:11.320 --> 08:15.020
Eingang und einen Steuereingang.

08:15.880 --> 08:20.980
Und jetzt, wenn S4, wenn dieser Steuereingang 0 ist, bedeutet das,

08:21.120 --> 08:25.020
dass das, was am Eingang des Demultiplexers anliegt, auf den 0.

08:25.140 --> 08:27.760
Ausgang durchgeschaltet werden muss.

08:28.420 --> 08:37.000
Bei einer 1 an S4 bedeutet das, dass das, was hier am Eingang anliegt,

08:37.160 --> 08:42.340
auf den Ausgang 1 des Demultiplexers durchgeschaltet werden soll.

08:42.340 --> 08:47.540
So, das heißt, wir haben hier Speicherbausteine, wir haben

08:47.540 --> 08:51.520
Multiplexer, Demultiplexer, sowohl hier als auch da, mit der gleichen

08:51.520 --> 08:52.560
Funktionalität.

08:53.120 --> 08:58.560
Und wir haben zwei Flipflops, das sind die hier grün markierten D

08:58.560 --> 08:59.400
-Flipflops.

08:59.900 --> 09:03.040
Aus dem Symbol erkennen die Informatiker, dass sie mit der

09:03.040 --> 09:07.160
ansteigenden Flanke hier durchschalten, durch dieses Symbol hier.

09:07.160 --> 09:12.120
Und diese Flipflops sind nichts anderes als ein Speicher für ein Bit.

09:13.020 --> 09:19.260
Das heißt, in einem einzigen Flipflop können wir ein Bit speichern,

09:19.420 --> 09:21.460
das heißt die Werte 0 oder 1.

09:23.040 --> 09:26.680
So, jetzt sollen wir aber die Funktion Antivalenz realisieren.

09:27.680 --> 09:34.920
Wir sehen hier, in diesem Rechenwerk haben wir ja aber kein GATA oder

09:34.920 --> 09:38.080
keine Einheit, die direkt die Antivalenz realisiert.

09:38.500 --> 09:43.200
Als logisches GATA haben wir das blau markierte NAND-GATA.

09:44.110 --> 09:47.360
Das ist für uns kein Problem, wie wir wissen aus der technischen

09:47.360 --> 09:51.160
Informatik 1, weil dieses NAND-GATA bzw.

09:51.460 --> 09:56.260
der NAND-Operator ein vollständiges Operatoren-System bildet.

09:56.700 --> 10:00.100
Und somit können wir beliebig gewünschte Funktionen mithilfe von

10:00.100 --> 10:03.080
diesem zweistelligen NAND-Operator beschreiben.

10:03.080 --> 10:08.760
Das heißt, um zunächst mal jetzt einen Algorithmus hier zu

10:08.760 --> 10:16.100
implementieren, welches die Funktion X1 Antivalent X2 realisiert, in

10:16.100 --> 10:21.900
diesem Rechenwerk müssen wir jetzt die Funktion X1 und X2 in eine NAND

10:21.900 --> 10:22.880
-Form umformen.

10:23.900 --> 10:31.200
Die Variablen X1 und X2 stehen ja hier im Speicherbaustein unter den

10:31.200 --> 10:33.220
Adressen 00 und 01.

10:33.540 --> 10:36.940
Der Speicherbaustein hat wie gesagt vier Speicherplätze.

10:38.440 --> 10:42.060
Das erkennt man daran, dass man hier zwei Adressleitungen hat.

10:42.480 --> 10:46.480
Das heißt, X1 ist an der Adresse 0, X2 an der Adresse 1.

10:46.480 --> 10:52.240
Das Ergebnis der Antivalenz von X1 und X2 soll an der Adresse 1.1

10:52.240 --> 10:53.260
abgelegt werden.

10:53.920 --> 10:57.340
Und die Speicherzelle, die dritte Speicherzelle, die noch verfügbar

10:57.340 --> 11:01.160
ist, die können wir zum Beispiel für Zwischenergebnisse benutzen.

11:01.940 --> 11:06.620
Außerdem haben wir hier einen Eingang bei diesem Speicherbaustein, der

11:06.620 --> 11:10.300
mit R slash W gekennzeichnet ist.

11:10.300 --> 11:16.240
Das deutet an, ob es jetzt bei dem Zugriff auf diesem Read-Access

11:16.240 --> 11:20.620
-Memory -Baustein um ein Lazy-Zugriff, das heißt, wenn R W das Signal

11:20.620 --> 11:26.480
1 ist, beziehungsweise um einen Schreibzugriff handelt, wenn dieses

11:26.480 --> 11:27.980
Signal den Wert 0 hat.

11:29.300 --> 11:31.740
So, das ist eigentlich die Aufgabenstellung.

11:31.900 --> 11:32.860
Haben wir das verstanden?

11:35.300 --> 11:38.560
Jetzt, wie geht man an diese Geschichte ran?

11:38.700 --> 11:39.920
Ich habe das angedeutet.

11:40.160 --> 11:45.700
Um jetzt die Antivalenzfunktion zu realisieren, müssen wir hier, da

11:45.700 --> 11:49.700
wir nur einen Nendgatter haben, die Antivalenzfunktion in eine

11:49.700 --> 11:51.640
Nendform bringen.

11:52.430 --> 11:58.940
Und wir wissen ja, dass die Antivalenzfunktion in ihre disjunktive

11:58.940 --> 12:06.400
Normalform als X1-X2 oder X1-X2-Quer geschrieben werden kann.

12:07.340 --> 12:11.900
Und damit wir das Ganze in eine Nendform bringen, können wir das Ganze

12:11.900 --> 12:15.800
jetzt zweimal negieren und demorgan anwenden.

12:15.800 --> 12:22.720
Daraus erhalten wir X1-Quer-Nend-X2 und das Ganze geklammert und dann

12:22.720 --> 12:25.460
nochmal Nend mit X1-Nend-X2.

12:26.800 --> 12:35.600
Das heißt, es tauchen hier nur zweistellige Nendoperatoren auf, die

12:35.600 --> 12:40.120
wir mithilfe von diesem einzigen Gatter in unserem Rechenwerk

12:40.120 --> 12:42.820
realisieren können.

12:42.820 --> 12:48.660
Zusätzlich tauchen hier natürlich die Negationen von Variablen wie X1

12:48.660 --> 12:49.040
-Quer.

12:49.780 --> 12:54.060
Wie bereits gesagt, der Nendoperator stellt ein vollständiges

12:54.060 --> 12:55.460
Operatoren -System dar.

12:55.560 --> 12:59.220
Das heißt, wir können auch die Negationen von Variablen hier

12:59.220 --> 13:00.320
realisieren.

13:00.520 --> 13:06.760
Und zwar X1-Quer ist nichts anderes als X-Nend-1 und X2-Quer ist

13:06.760 --> 13:09.000
nichts anderes als X2-Nend-1.

13:10.000 --> 13:15.800
Das heißt, auch die Invertierung oder die Negation der einzigen

13:15.800 --> 13:19.780
Variablen können wir mithilfe von diesem Nend-Gatter realisieren.

13:21.560 --> 13:26.300
Das heißt, wir haben jetzt die Voraussetzungen geschaffen, um

13:26.300 --> 13:33.260
praktisch den Algorithmus zur Realisierung der Antivalenzfunktion zu

13:33.260 --> 13:34.020
implementieren.

13:35.020 --> 13:45.320
Was uns noch fehlt, ist natürlich die Belegung der Steuereingänge der

13:45.320 --> 13:49.480
Multiplexer und Demultiplexer, um die richtigen Datenflüsse

13:49.480 --> 13:51.280
realisieren zu können.

13:51.280 --> 14:01.280
Das heißt, die Variablen X1 und X2 stehen ja hier im Speicherbaustein.

14:02.420 --> 14:07.940
Wir müssen sie irgendwie an den Eingängen von diesem Nend-Gatter

14:07.940 --> 14:12.800
bringen und die entsprechenden Operationen ausführen, und zwar mehr

14:12.800 --> 14:13.480
als einmal.

14:13.480 --> 14:17.960
Wir müssen für die Negation von X1 einmal eine Nend-Operation

14:17.960 --> 14:21.800
ausführen, für die Negation von X2 und nochmal für die restlichen

14:21.800 --> 14:22.760
Operationen.

14:23.760 --> 14:29.080
Dazu müssen wir natürlich, zunächst einmal nehmen wir mal an, wir

14:29.080 --> 14:31.660
wollen ja X1 quer bilden.

14:31.920 --> 14:42.440
Wir wissen, dass X1 Antivalent X2 ist nichts anderes als X1 quer Nend

14:42.440 --> 14:48.520
X2 und das Ganze nochmal Nend X1 Nend X2 quer.

14:48.520 --> 14:50.520
Das haben wir ermittelt.

14:51.320 --> 14:56.500
Das heißt, wir brauchen zunächst mal X1 und das müssen wir ja

14:56.500 --> 14:57.540
negieren.

14:58.380 --> 15:03.120
Negieren ist ja kein Problem, haben wir gesagt, weil X1 quer ist

15:03.120 --> 15:07.300
nichts anderes als X1 Nend 1.

15:07.300 --> 15:11.860
Und X1 haben wir Gott sei Dank hier in diesem Schaltwerk da.

15:12.720 --> 15:16.640
Das heißt, das ist hier der Eingang von diesem Multiplexer.

15:17.260 --> 15:21.640
Das heißt, wir sorgen dafür, dass diese 1 hier landet.

15:22.520 --> 15:28.380
Dazu müssen wir praktisch am Steuereingang S2 den Wert 0 anlegen,

15:28.560 --> 15:31.880
damit der Eingang hier auf den Ausgang durchgeschaltet wird.

15:32.700 --> 15:37.840
Und dann müssen wir dafür sorgen, dass an dem zweiten Eingang hier X1

15:37.840 --> 15:38.440
anliegt.

15:38.520 --> 15:42.020
X1 ist noch hier drin, an der Adresse 00.

15:42.920 --> 15:47.360
Das heißt, wir greifen lesend auf diesen Speicherbaustein.

15:48.580 --> 15:53.280
Wir holen X1, also wir greifen auf die Adresse 00, wo X1 steht.

15:53.280 --> 15:56.780
Wir holen X1, X1 steht hier.

15:57.660 --> 16:04.860
Jetzt sorgen wir dafür, dass X1 an dem Eingang von dem Demultiplexer

16:04.860 --> 16:08.820
landet, dann wiederum hier rückgekoppelt wird.

16:08.820 --> 16:13.160
Das kommt hierher zu dem Eingang und wir wollen hier ran.

16:13.920 --> 16:18.000
Das heißt, wir müssen hier dafür sorgen, dass wir praktisch diesen

16:18.000 --> 16:25.060
Pfad bekommen, um X1 an den Eingang von diesem NAND-Gatter zu bringen.

16:26.010 --> 16:31.760
Ja, dazu brauchen wir nichts anderes als die Werte der Steuervariablen

16:31.760 --> 16:36.780
des Demultiplexers geeignet zu wählen.

16:36.780 --> 16:40.840
Denn, damit hier der 0.

16:40.940 --> 16:45.580
Eingang ausgewählt werden kann, muss es 3, den Wert 0, haben.

16:46.260 --> 16:51.900
Damit der erste Ausgang von dem Demultiplexer hier ausgewählt wird,

16:52.240 --> 16:54.900
muss es 4, den Wert 1, haben.

16:55.800 --> 17:02.360
Damit der Ausgang 1 von dem Demultiplexer hier ausgewählt wird, muss

17:02.360 --> 17:04.060
es 1, den Wert 1, haben.

17:05.160 --> 17:11.200
Und wenn wir alles in der Form, also diese Steuervariablen, so

17:11.200 --> 17:14.500
festlegen, dann haben wir X1 an der Stelle.

17:14.500 --> 17:19.840
Das heißt hier am Ausgang haben wir X1 NAND1, also X1².

17:20.340 --> 17:26.820
X1² ist am Eingang von einem Flipflop, kann dort abgespeichert werden.

17:29.560 --> 17:33.500
Wir wollen hier natürlich, das Ganze ist jetzt sehr idealisiert

17:33.500 --> 17:42.060
betrachtet, wir wollen hier davon ausgehen, dass alle Auswirkungen im

17:42.060 --> 17:49.840
Rechenwerk hier abgeklungen sind, bevor jetzt der Takt sich erneut

17:49.840 --> 17:50.320
ändert.

17:50.320 --> 17:56.220
Das heißt die Taktfrequenz ist so gewählt, dass diese Änderungen im

17:56.220 --> 18:02.480
Rechenwerk abgeklungen sind, bevor jetzt der Takt den Wert oder seinen

18:02.480 --> 18:04.400
Pegel nochmal ändert.

18:04.400 --> 18:11.560
Okay, dann wollen wir ja das Ganze hier machen und zwar für die

18:11.560 --> 18:13.260
Antivalenzfunktion.

18:14.060 --> 18:18.920
Also wir müssen ja die zur Steuerung des Datenflusses notwendigen

18:18.920 --> 18:24.180
Bitkombinationen, also Belegungen der Steuervariablen der Multiplexer

18:24.180 --> 18:24.740
bzw.

18:25.060 --> 18:29.800
Demultiplexer eingeben, die zur Berechnung der Antivalenz notwendig

18:29.800 --> 18:30.000
sind.

18:30.000 --> 18:35.940
Die Bitkombinationen wollen wir zeilenweise in eine Tabelle eintragen,

18:36.080 --> 18:39.280
wobei jede Zeile einer Periode des Taktes entspricht.

18:40.740 --> 18:46.120
Und wenn bei einer bestimmten Aktion, das heißt in einer Zeile, der

18:46.120 --> 18:50.840
RAM -Baustein angesprochen wird, entweder wenn wir lesend oder

18:50.840 --> 18:58.340
schreibend darauf zugreifen, so soll man in diesem Fall die Adresse in

18:58.340 --> 18:59.640
dieser Tabelle eintragen.

19:00.000 --> 19:03.680
Also die Adresse der Speicherzelle im RAM-Baustein, auf die man gerade

19:03.680 --> 19:04.340
zugreift.

19:05.360 --> 19:10.160
Hier ist nochmal unser Rechenwerk, einfaches Rechenwerk abgebildet.

19:10.300 --> 19:15.700
Die Flipflops habe ich hier gekennzeichnet mit FFA, also Flipflop

19:15.700 --> 19:24.020
-Ausgang von dem UND-Gatter und der Flipflop, der am Eingang von dem

19:24.020 --> 19:25.700
NAND -Gatter sich befindet.

19:27.260 --> 19:33.220
Und das Ganze, was ich gerade gemacht habe für X1, ist nochmal hier

19:33.220 --> 19:34.100
dargestellt.

19:34.720 --> 19:43.860
Das heißt, um X1 quer bilden zu können, greifen wir lesend auf das RAM

19:43.860 --> 19:44.990
-Baustein zu.

19:46.050 --> 19:50.730
X1 ist an der Adresse 0,0, das heißt wir greifen auf die Adresse 0,0.

19:52.610 --> 19:58.890
S3 muss hier den Wert 0 haben, damit wir so fahren.

20:03.270 --> 20:09.850
S4 muss den Wert 1 haben, damit wir so rumkommen.

20:12.030 --> 20:17.510
S1 muss den Wert 1 haben, damit wir X1 an dieser Stelle hier bekommen.

20:18.590 --> 20:20.910
Also S1 muss den Wert 1 haben.

20:20.910 --> 20:26.190
Und damit wir diese 1 hier an den Eingang hier bekommen, muss S2 den

20:26.190 --> 20:26.990
Wert 0 haben.

20:28.910 --> 20:32.910
Das heißt, bei dieser Bit-Kombination, das ist ja eine Zeile, das

20:32.910 --> 20:37.670
geschieht ja in der ersten Taktperiode, haben wir dafür gesorgt, dass

20:37.670 --> 20:44.470
X aus dem RAM-Baustein geholt wurde und mit dem 1 hier NAND verknüpft,

20:44.550 --> 20:50.590
sodass wir ein X1 quer im Flipflop-FFA haben.

20:50.910 --> 20:55.030
Das heißt, als Kommentar können wir hier dazu schreiben, kontrollieren

20:55.030 --> 21:01.190
wir, ob das stimmt, können wir schreiben, X1 quer bilden und in das

21:01.190 --> 21:03.410
Flipflop -FFA speichern.

21:03.850 --> 21:07.110
Das heißt, hier haben wir X1 quer im Moment.

21:08.610 --> 21:16.330
Der nächste Schritt ist, dass wir X1 quer, was hier ist,

21:28.230 --> 21:30.070
mit X2 NAND verknüpfen.

21:31.650 --> 21:36.450
Auf die gleiche Art und Weise können wir natürlich X2 aus dem RAM

21:36.450 --> 21:37.390
-Baustein holen.

21:37.390 --> 21:40.030
Das heißt, X2 können wir hier.

21:45.870 --> 21:49.250
Dann hätten wir hier X2, das wäre ja wunderbar.

21:49.770 --> 21:54.430
Den Weg kennen wir, das heißt, wir kennen alle Bit-Kombinationen, die

21:54.430 --> 21:58.790
notwendig sind, um X2 aus dem RAM-Baustein zu holen.

21:58.790 --> 22:01.910
Mit dem Unterschied, dass wir jetzt, statt die Adresse 0,0

22:01.910 --> 22:07.110
anzusprechen, die Adresse 0,1, also von X2 hier anlegen müssen.

22:07.930 --> 22:15.370
Ja, um das hier aber bilden zu können, muss ja X1 quer an den zweiten

22:15.370 --> 22:21.770
Eingang von dem Gatter hier gebracht werden.

22:21.770 --> 22:24.710
Das heißt, hier muss X1 quer kommen.

22:25.630 --> 22:29.510
Aber X1 quer befindet sich noch in dem Flip-Flop A.

22:31.410 --> 22:36.190
Man sieht hier, wenn wir dafür sorgen, dass X1 zunächst mal in das

22:36.190 --> 22:42.630
Flip -Flop E transferiert wird, dann können wir anschließend hier über

22:42.630 --> 22:50.770
die Steuervariable X2, X1 quer auf den entsprechenden Eingang vom NAND

22:50.770 --> 22:51.470
-Gatter legen.

22:52.350 --> 22:58.550
Das heißt, das machen wir zuerst, weil wenn wir zuerst X1 holen und

22:58.550 --> 23:03.350
eine Operation hier ausführen, dann würde das Ergebnis der Operation

23:03.350 --> 23:07.930
auch im Ausgangs-Flip-Flop landen und somit das alte Ergebnis

23:07.930 --> 23:08.590
überschreiten.

23:09.630 --> 23:14.810
Eine andere Möglichkeit wäre natürlich, dass wir das schon berechnete

23:14.810 --> 23:19.130
Ergebnis in die noch zur Verfügung stehenden Speicherzelle im RAM

23:19.130 --> 23:20.370
-Baustein abspeichern.

23:21.030 --> 23:23.110
Aber das geht so einfacher.

23:23.110 --> 23:28.970
Das heißt, wir transferieren zunächst mal X1 quer von dem Flip-Flop A

23:28.970 --> 23:30.570
in das Flip-Flop E.

23:31.610 --> 23:43.110
Und das ist eigentlich der Weg, den wir einschlagen müssen.

23:47.550 --> 23:49.750
Und dann hier rein.

23:50.750 --> 23:51.310
Das heißt,

24:03.560 --> 24:09.920
wir müssen die Steuervariable S1 auf 0 setzen, damit der Ausgang hier

24:09.920 --> 24:11.060
ausgewählt werden kann.

24:11.740 --> 24:16.700
S2 ist irrelevant eigentlich für uns, weil das Ergebnis steht ja schon

24:16.700 --> 24:16.980
da.

24:17.920 --> 24:24.960
S3 müssen wir auf 1 setzen, damit wir den Eingang hier von der

24:24.960 --> 24:26.180
Multiplexer auswählen.

24:26.820 --> 24:29.060
Und S4 müssen wir auf 1 setzen.

24:29.960 --> 24:36.180
In diesem Taktzyklus sprechen wir keine Hauptspeicheradresse an, also

24:36.180 --> 24:38.880
keine Adresse im RAM-Baustein.

24:38.880 --> 24:46.080
Deshalb sind die Bits hier A1 und A0 als Don't-Care angegeben und

24:46.080 --> 24:48.260
genauso der Fall für S2.

24:48.920 --> 24:56.560
Das Re-Drive-Signal steht nach wie vor auf 1.

24:56.560 --> 25:05.000
Im nächsten Schritt können wir natürlich X2 holen aus dem RAM

25:05.000 --> 25:05.740
-Baustein.

25:06.380 --> 25:12.800
Dazu greifen wir auf die Adresse 01, lesen und dann bringen wir X2

25:12.800 --> 25:14.540
hier an dieser Stelle.

25:15.580 --> 25:19.560
Und X1² haben wir ja schon hier in diesem Flip-Flop.

25:19.700 --> 25:25.600
Das heißt, wir müssen S2 nur auf 1 setzen, damit wir hier X1² und X2

25:25.600 --> 25:27.880
an den Eingängen von diesem NAND-Gatter haben.

25:28.620 --> 25:35.420
So, als Ergebnis haben wir dann den ersten Term in dem Flip-Flop A.

25:37.600 --> 25:42.340
Jetzt müssen wir den zweiten Term hier berechnen.

25:42.940 --> 25:46.000
Und wir haben gesehen, dass wir zur Berechnung von dem ersten Term

25:46.000 --> 25:49.060
schon beide Flip-Flops immer gleichzeitig benötigt haben.

25:49.060 --> 25:53.280
Deshalb ist es sinnvoll, dass wir jetzt das Ergebnis hier, was in dem

25:53.280 --> 25:58.180
Flip -Flop A steht, in das RAM-Baustein schreiben.

25:58.500 --> 26:03.980
Und zwar an der Stelle, die für das Zwischenergebnis reserviert ist.

26:04.140 --> 26:07.900
Das heißt, Speicherzelle mit der Adresse 2.

26:07.900 --> 26:13.500
Das heißt, unser Ergebnis hier steht da.

26:14.560 --> 26:25.820
Wir müssen jetzt dafür sorgen, dass das Ergebnis hier über diesen Weg

26:25.820 --> 26:29.640
in das RAM-Baustein eingeschrieben wird.

26:29.640 --> 26:32.320
So, das ist ein Schreibzugriff.

26:32.500 --> 26:35.020
Das heißt, der Serie-3-Signal muss 0 sein.

26:35.840 --> 26:40.780
Wir greifen schreibend auf die Adresse 2, deshalb die Signale A1 und

26:40.780 --> 26:42.740
A0 so belegt.

26:43.460 --> 26:50.520
S3 muss ja den Wert 1 haben und S4 muss den Wert 0 haben, damit der

26:50.520 --> 26:53.540
Null -T-Ausgang von dem D-Multiplexer ausgewählt wird.

26:54.120 --> 26:57.820
S1 und S2 sind in diesem Taktzyklus unwichtig.

26:59.760 --> 27:07.580
Im zweiten Schritt können wir natürlich X2 querbilden und in das Flip

27:07.580 --> 27:12.080
-Flop A schreiben, also analog zu der Vorgehensweise bis jetzt.

27:12.080 --> 27:20.300
Dann den Inhalt von dem Flip-Flop A in das Flip-Flop E transferieren

27:20.300 --> 27:26.920
und anschließend X1 holen und NAND verknüpfen mit X2 quer, was ja in

27:26.920 --> 27:28.380
dem Eingang-Flip-Flop steht.

27:28.380 --> 27:30.440
Das heißt, das machen wir jetzt hier.

27:30.960 --> 27:34.920
Die entsprechenden Bit-Kombinationen sollen ja identisch sein mit

27:34.920 --> 27:36.360
denen hier.

27:36.380 --> 27:40.340
Das heißt, das hier ist identisch mit dem hier bis auf die Adresse.

27:41.420 --> 27:45.280
Weil wir hier X1 geholt haben, hier holen wir X2.

27:45.960 --> 27:50.300
Im zweiten Schritt der Transferbefehl, das ist ja der gleiche.

27:50.880 --> 27:57.440
Und im dritten Schritt ist das auch identisch bis auf die Adressierung

27:57.440 --> 27:58.480
von X1.

27:58.480 --> 28:03.760
Das heißt, hier haben wir X2 adressiert, um das NAND verknüpfen zu

28:03.760 --> 28:04.960
können mit X1.

28:05.380 --> 28:11.160
Hier müssen wir X1 aus dem RAM-Baustein holen und mit dem Inhalt von

28:11.160 --> 28:13.300
FFE NAND verknüpfen.

28:14.190 --> 28:26.800
So, das heißt, in diesem Moment haben wir der zweite Term ist hier in

28:26.800 --> 28:33.680
diesem Flip-Flop A und der erste Term ist hier im Speicher-Baustein.

28:34.680 --> 28:41.340
Ja, das heißt, wir können eigentlich jetzt nochmal den Inhalt von dem

28:41.340 --> 28:48.020
Flip -Flop A in das Flip-Flop E transferieren und anschließend, das

28:48.020 --> 28:57.060
heißt hier haben wir dann 1 und anschließend greifen wir lesend auf

28:57.060 --> 29:04.540
den Speicher-Baustein, holen wir den Term 2 und verknüpfen das mit

29:04.540 --> 29:10.260
NAND mit dem Inhalt von dem Eingang-Flip-Flop und somit erhalten wir

29:10.260 --> 29:18.300
halt X1 Antivalent X2 und zwar in dem Ausgang-Flip-Flop FA.

29:19.020 --> 29:23.180
Das Ergebnis, das Endergebnis sollen wir aber wiederum im Speicher

29:23.180 --> 29:26.540
-Baustein schreiben und zwar in der Adresse 1.1.

29:26.660 --> 29:32.340
Wenn das hier ist, dann müssen wir eigentlich durch eine geeignete

29:32.340 --> 29:36.980
Auswahl der Steuerleitungen oder der Belegung der Steuervariablen

29:36.980 --> 29:42.440
dafür sorgen, dass der Grunipfad hier nach oben eingeschlagen wird.

29:42.440 --> 29:49.140
Das heißt, das ist eigentlich nichts anderes als ein Schreibezugriff

29:49.140 --> 29:53.980
auf den Speicher-Baustein und zwar an der Adresse 1.1.

29:54.640 --> 30:01.760
S3 muss den Wert 1 haben, S4 muss den Wert 0 haben, S1 und S2 sind in

30:01.760 --> 30:04.560
diesem Taktzyklus unbeteiligt bzw.

30:04.860 --> 30:05.340
unwichtig.

30:06.760 --> 30:16.120
So, wie wir sehen, haben wir eine Implementierung der Antivalent

30:16.120 --> 30:20.120
-Funktion mithilfe von einem einfachen Rechenwerk hier realisiert,

30:21.540 --> 30:27.680
indem wir diese Antivalent-Funktion zunächst einmal in eine Nennform

30:27.680 --> 30:34.420
gebracht haben, weil unser Rechenwerk nur die logische Operation Nend

30:34.420 --> 30:35.080
erlaubt.

30:36.140 --> 30:42.060
Wir haben durch eine Reihe von Transfer-Operationen, also von Register

30:42.060 --> 30:48.180
-Transfer -Operationen, in dem Fall hier sind das 10-Takt-Zyklen,

30:48.660 --> 30:53.960
dafür gesorgt, dass das Ergebnis der Antivalent von X1 und X2, die ja

30:53.960 --> 30:59.420
im RAM-Baustein standen, an der Adresse 0 und 1 berechnet wurde und

30:59.420 --> 31:02.100
wiederum im RAM-Baustein abgespeichert wurde.

31:02.760 --> 31:10.960
So, das heißt, diese Tabelle hier, diese Belegung der Eingangsvariable

31:10.960 --> 31:16.640
ist eigentlich der Schlüssel zur Ausführung von der Operation

31:16.640 --> 31:17.600
Antivalent.

31:17.600 --> 31:23.820
Für uns Menschen ist es natürlich sehr umständlich, derartige Bit

31:23.820 --> 31:28.080
-Kombinationen und 0-1-Dont-Care-Kolonnen zu merken bzw.

31:28.300 --> 31:28.960
zu schreiben.

31:30.140 --> 31:35.180
Einfacher wären solche Anweisungen, die hier im Kommentarfeld

31:35.180 --> 31:36.220
eingegeben sind.

31:37.220 --> 31:45.880
Und wenn man noch eine Stufe weiter geht, dann würde man sagen, man

31:45.880 --> 31:51.120
lege hierzu eine Programmiersprache mit einer bestimmten Notation vor,

31:52.520 --> 31:57.060
weil, wenn wir diese Anweisungen hier betrachten, dann tauchen ja

31:57.060 --> 32:00.480
immer wieder die gleichen Anweisungen auf, aber mit anderen Operanten.

32:01.180 --> 32:09.300
Zum Beispiel, wir haben ja hier eine Transferanweisung.

32:09.740 --> 32:11.300
Das ist ja immer die gleiche.

32:11.520 --> 32:15.380
Der Inhalt vom Flipflop A wird in das Flipflop E transferiert.

32:16.380 --> 32:21.720
Wir haben derartige Anweisungen, wo wir auf den Speicherbaustein

32:21.720 --> 32:26.580
zugreifen, auf eine bestimmte Adresse den Inhalt lesen, Nend

32:26.580 --> 32:32.700
verknüpfen mit irgendwas anderem und das Ergebnis im Flipflop A

32:32.700 --> 32:33.300
speichern.

32:33.300 --> 32:36.720
Das heißt, es ist eigentlich eine Nend-Operation.

32:37.420 --> 32:41.880
Optional kann man dazu die Adresse von einem Operanten im RAM-Baustein

32:41.880 --> 32:42.360
eingeben.

32:42.980 --> 32:54.500
Das heißt, derartige Operationen hier, das auch, das auch, das auch

32:54.500 --> 32:57.400
und das auch, die sind ja auch gleich.

32:57.400 --> 33:03.120
Es ist immer eine Nend-Operation von dem Flipflop E.

33:03.480 --> 33:06.120
Irgendetwas, was im Flipflop E steht.

33:06.620 --> 33:13.820
Entweder X1 quer oder eigentlich die 1 zur Negation mit dem Inhalt von

33:13.820 --> 33:14.800
dem Flipflop A.

33:14.800 --> 33:20.020
Ja, und was haben wir noch an Operationen?

33:20.100 --> 33:25.840
Wir haben hier eine andere Art von Transfer-Operationen, und zwar der

33:25.840 --> 33:29.300
Inhalt von dem Flipflop A in das RAM-Baustein.

33:33.530 --> 33:37.470
Damit beschäftigt sich der dritte Teil dieser Aufgabe, und zwar wir

33:37.470 --> 33:42.370
sollten eine Programmiersprache, in Anführungsstrichen, das heißt

33:42.370 --> 33:48.330
Befehle in lesbarem Quellcode entwerfen, wobei ein Befehl einer Zeile

33:48.330 --> 33:50.490
der Tabelle entspricht.

33:50.490 --> 33:56.430
Jeder Befehl soll die auszuführende Operation und gegebenenfalls die

33:56.430 --> 34:01.150
RAM -Adresse enthalten, falls da ein Zugriff auf den RAM-Baustein

34:01.150 --> 34:04.710
durch den entsprechenden Befehl erfolgt.

34:05.710 --> 34:10.590
Also, wenn wir das Ganze hier einmal betrachten, dann sehen wir, dass

34:10.590 --> 34:19.410
wir hier zunächst einmal eine Art Negationsbefehl brauchen, wo man

34:19.410 --> 34:22.910
optional eine Adresse vom RAM-Baustein eingeben kann.

34:22.910 --> 34:28.430
Das heißt, das Bit an der Adresse XY im RAM-Baustein wird geholt,

34:28.570 --> 34:32.810
invertiert und das Ergebnis im Flipflop A gespeichert.

34:32.810 --> 34:36.990
Das wäre zum Beispiel das hier der Fall, oder das hier der Fall.

34:37.110 --> 34:41.610
Das Bit X1 oder X2 wird geholt, deshalb werden die entsprechenden

34:41.610 --> 34:52.390
Stellen adressiert und geholt, invertiert und im Flipflop A

34:52.390 --> 34:53.830
abgespeichert.

34:53.830 --> 34:59.610
Die nächste Operation wäre eine Nend-Operation, wobei man hier auch

34:59.610 --> 35:04.150
bei Zugriff auf den RAM-Baustein eine Adresse eingeben kann.

35:04.950 --> 35:10.590
Das heißt, das Bit an der angegebenen Adresse holen und mit dem Bit im

35:10.590 --> 35:15.230
Flipflop E durch die Nend-Funktion verknüpfen.

35:15.230 --> 35:19.830
Das Ergebnis steht dann anschließend in FA.

35:20.370 --> 35:23.730
Das wären zum Beispiel derartige Operationen hier.

35:27.850 --> 35:33.570
Und als dritter Befehl haben wir ja ein Transferbefehl.

35:34.150 --> 35:38.330
Transferiere den Inhalt vom Ausgangsregister oder vom Ausgangs

35:38.330 --> 35:42.350
-Flipflop A in das Eingangs-Flipflop E.

35:42.350 --> 35:47.870
Und viertens brauchen wir ja zum Speichern von dem Inhalt von dem

35:47.870 --> 35:53.530
Ausgangs -Flipflop im RAM-Baustein sowas wie etwas Store oder

35:53.530 --> 36:00.830
Speichere an der angegebenen Adresse, und zwar den Inhalt von dem

36:00.830 --> 36:02.590
Ausgangs -Flipflop A.

36:03.400 --> 36:08.670
Das heißt, dieses Mikro-Programm, dieses Register-Transfer-Programm,

36:08.690 --> 36:12.770
das wir vorher kennengelernt haben oder entwickelt haben, können wir

36:12.770 --> 36:17.130
eigentlich mithilfe von einem lesbaren Code hier eingeben.

36:17.130 --> 36:25.110
Und zwar, hier greifen wir auf X1, das heißt NAT X1, NAT 00, auf die

36:25.110 --> 36:25.930
Adresse 00.

36:27.530 --> 36:33.250
Das Bit wird geholt, invertiert und in das Ausgangs-Flipflop A

36:33.250 --> 36:34.130
gespeichert.

36:34.130 --> 36:39.870
Transferiere den Inhalt von A nach E, verknüpfe den Inhalt vom

36:39.870 --> 36:48.170
Flipflop E mit dem Inhalt an der Adresse 01 vom Speicher-Baustein,

36:49.830 --> 36:55.570
speichere das Zwischenergebnis an der Adresse 02 im RAM-Baustein, und

36:55.570 --> 37:00.550
nochmal hier NAT transferiere und NAND, und anschließend transferiere,

37:01.150 --> 37:05.270
und dann nochmal bei die Termi, also bei den Klammern, miteinander

37:05.270 --> 37:09.830
NAND verknüpfen und anschließend SDA, das heißt das Ergebnis an der

37:09.830 --> 37:13.990
Adresse 03 im RAM-Baustein abspeichern.

37:15.070 --> 37:16.770
Gibt es Fragen dazu?

37:19.830 --> 37:21.670
Nein, war die Aufgabe sinnvoll?

37:25.190 --> 37:32.470
Gut, ein möglicher Test für die Tests, die wir leider nicht mehr

37:32.470 --> 37:35.950
machen werden hier in der Größenübung, wäre das hier.

37:38.390 --> 37:43.150
Geben Sie ein Programm zur Berechnung der Äquivalenzfunktion an mit

37:43.150 --> 37:44.450
dem gleichen Rechenwerk.

37:45.350 --> 37:48.370
Und dazu hätte ich euch sechs Minuten Zeit gegeben.

37:52.580 --> 37:55.200
So, wie geht man ran?

37:56.260 --> 37:57.260
Was ist der Unterschied?

37:59.480 --> 38:04.040
Kommt man mit diesen vier Befehlen, die wir spezifiziert haben, aus,

38:04.940 --> 38:10.720
oder ist die Äquivalenz bezüglich dieses Schaltwerkes schlimmer als

38:10.720 --> 38:11.600
die Antivalenz?

38:13.980 --> 38:18.120
Ja, das Erste, was man machen muss natürlich, als Lösung hätte ich

38:18.120 --> 38:24.160
erwartet, die Äquivalenz kann ich so schreiben, das heißt, es muss

38:24.160 --> 38:28.680
disjunktiv in Normalform, also die Informationswerte hätten den Test

38:28.680 --> 38:30.280
nicht mitgemacht, das ist klar.

38:30.280 --> 38:35.180
Weil das ist ungerecht, da kommt viel Wissen aus der technischen

38:35.180 --> 38:40.520
Informatik eins mit hier rein und deshalb hätte dieser Test für die

38:40.520 --> 38:42.240
Informationswerte nicht gezählt.

38:42.240 --> 38:49.880
So, das heißt, die Äquivalenz in Normalform bringen und jetzt

38:49.880 --> 38:54.000
überlegen wir uns, können wir eigentlich die gleiche Reihenfolge der

38:54.000 --> 38:59.920
Befehle oder die gleichen Befehle benutzen, die wir für die Antivalenz

38:59.920 --> 39:00.560
benutzt haben?

39:04.350 --> 39:05.750
Ja.

39:07.170 --> 39:10.010
Okay, wer meint Ja?

39:12.090 --> 39:14.990
Wer meint Nein?

39:21.150 --> 39:23.850
Wer hätte den Test mitgemacht?

39:30.210 --> 39:35.590
Okay, also ich sehe ein kleines Problem hier bei der Äquivalenz in der

39:35.590 --> 39:35.890
Form.

39:36.110 --> 39:41.410
Und zwar, wenn ich jetzt hier X1 quer bilde, dann habe ich ja das

39:41.410 --> 39:42.270
Ergebnis hier.

39:42.270 --> 39:55.350
Dann transferiere ich X1 quer hierher und hole X2 quer und muss X2

39:55.350 --> 39:58.350
quer bilden, das heißt, ich kriege X2 quer hier.

39:59.030 --> 40:06.350
So, jetzt können wir die beiden natürlich miteinander verknüpfen,

40:06.350 --> 40:11.150
indem wir X1 quer hier holen und X2 quer hier holen.

40:13.450 --> 40:25.530
So, das Ergebnis steht wiederum hier und müssen wir natürlich hier

40:25.530 --> 40:30.730
zwischenspeichern, weil wir das Flipflop für die weitere Operation

40:30.730 --> 40:36.390
brauchen, also für X1, weil wir X1 holen müssen und dann X1 und X2

40:36.390 --> 40:38.150
miteinander verknüpfen.

40:38.150 --> 40:43.070
Und wenn wir dieses Ergebnis hier gespeichert haben, dann brauchen wir

40:43.070 --> 40:48.350
das Ergebnis wiederum an den Eingang von dem hier, ohne über dieses

40:48.350 --> 40:51.610
Flipflop hier zu fahren oder zu gehen.

40:51.610 --> 40:59.350
Das heißt, eigentlich brauchen wir hier etwas wie Load, also das ist

40:59.350 --> 41:06.070
eine andere Variante der Lösung, wo man jetzt hier das Ergebnis hier

41:06.070 --> 41:15.270
an der Speicherzelle 1.0 gespeichert hat und im zweiten Teil brauchen

41:15.270 --> 41:16.510
wir ja X1.

41:17.310 --> 41:21.530
X1 müssen wir natürlich aus der Stelle hier lesen und mit den

41:21.530 --> 41:25.910
Operationen, die wir da eingeführt haben, haben wir keine derartige

41:25.910 --> 41:31.590
Hole -Operation, ohne jetzt das Bit oder den Inhalt der Adresse zu

41:31.590 --> 41:36.490
invertieren und an den entsprechenden Eingang hier zu legen.

41:36.490 --> 41:41.870
Das heißt hier würde man zusätzlich mit Hilfe von einem Load-ähnlichen

41:41.870 --> 41:47.550
Befehl, also laden Inhalt von der Adresse so und so im Speicher

41:47.550 --> 41:49.890
auskommen oder brauchen.

41:50.950 --> 41:58.330
Okay, nun zur Ausführung jetzt von diesem Programm müssen wir für die

41:58.330 --> 42:03.310
Hardware diese Bit-Kombinationen oder diese Tabelle, die wir erstellt

42:03.310 --> 42:04.790
haben, irgendwo ablegen.

42:04.790 --> 42:10.910
Und wenn es heißt jetzt Antivalence oder Äquivalenz ausführen, muss

42:10.910 --> 42:16.750
jetzt diese Tabelle, das heißt diese Belegung der Steuereingänge der

42:16.750 --> 42:26.930
Multiplexer und Demultiplexer von einem sozusagen Steuerwerk, also der

42:26.930 --> 42:31.070
ja die Ausführung kontrolliert und sagt, jetzt ist das Ergebnis da

42:31.070 --> 42:33.690
nach 10 Taktzyklen bzw.

42:34.710 --> 42:38.790
der praktisch dafür sorgt, dass in jedem Taktzyklus hier die

42:38.790 --> 42:43.390
entsprechenden Steuersignale für die Multiplexer und Demultiplexer

42:43.390 --> 42:45.170
richtig gesetzt werden.

42:45.170 --> 42:53.930
Das heißt, hier diese Belegungstabelle oder diese Bit-Kombinationen,

42:53.950 --> 43:00.110
die wir ja erarbeitet haben hier, könnte man in einem Festwertspeicher

43:00.110 --> 43:05.530
hier ablegen und zusätzlich, also das Steuerwerk könnte hier nach dem

43:05.530 --> 43:08.170
Schema hier realisiert werden.

43:08.170 --> 43:11.850
Das heißt, die Ausführung von dem Programm würde dann nach dem

43:11.850 --> 43:15.730
Aktivieren von einem Startsignal hier erfolgen.

43:16.870 --> 43:21.250
Nach dem Aktivieren von diesem Startsignal werden die entsprechenden

43:21.250 --> 43:26.110
Signale hier gesetzt, weil ja unsere Nullen und Eins sind hier in

43:26.110 --> 43:29.210
diesem ROM-Baustein abgespeichert werden.

43:29.210 --> 43:35.890
Dazu könnte man sich einen Zähler vorstellen, der zwei Eingänge hat.

43:36.030 --> 43:43.590
Einmal einen Eingang zum Rücksetzen des Zählers, also nach dem Beenden

43:43.590 --> 43:46.570
der Ausführung des Programms, bzw.

43:46.950 --> 43:51.630
einen Eingang zur Freigabe der Zählfunktion, damit jetzt die Anzahl

43:51.630 --> 43:53.570
der Schritte bzw.

43:54.370 --> 44:01.010
der Taktzyklen gezählt werden kann, die zur Ausführung von Antivalence

44:01.010 --> 44:01.790
bzw.

44:02.050 --> 44:03.570
Equivalence notwendig sind.

44:04.730 --> 44:07.310
Okay, gibt es Fragen dazu?

44:10.010 --> 44:11.990
Naja, dann machen wir weiter.

44:12.690 --> 44:17.570
Und zwar mit einer weiteren Aufgabe, oder mit einer zweiten Aufgabe,

44:17.830 --> 44:21.090
die das Thema auch Mikroprogrammierung behandelt.

44:21.490 --> 44:25.110
Die Mikroprogrammierung haben wir, wie gesagt, am Ende der Technischen

44:25.110 --> 44:31.310
Informatik I kurz erläutert, im Zusammenhang mit der Registertransfer

44:31.310 --> 44:31.690
-Ebene.

44:31.690 --> 44:35.490
Bei dieser Schaltung hier haben wir eine arithmetisch-logische

44:35.490 --> 44:41.450
Einheit, also ein Rechenwerk hier, welches nicht nur wie unser

44:41.450 --> 44:47.830
einfaches Rechenwerk die Nennverknüpfung ausführen kann, sondern kann

44:47.830 --> 44:52.230
vielleicht addieren, subtrahieren, multiplizieren, dividieren und

44:52.230 --> 44:53.530
irgendwelche andere Sachen.

44:53.530 --> 44:58.730
Man kann eigentlich nur vier Sachen machen, wenn man hier nur zwei

44:58.730 --> 44:59.870
Steuereingänge hat.

45:00.830 --> 45:06.150
Und diese Schaltung besteht zunächst einmal aus einem Bus, also einer

45:06.150 --> 45:11.990
Ansammlung von Leitungen der Breite 16 Bit, also da können Datenwörter

45:11.990 --> 45:15.210
der Breite 16 Bit über diesen Bus hier transferiert werden.

45:17.030 --> 45:22.550
Mehrere Register, das ist einmal das Register X, das Register Y, das

45:22.550 --> 45:25.250
Register A und das Register B.

45:28.470 --> 45:36.470
Und diese Register haben ja bestimmte Steuersignale, das ist einmal

45:36.470 --> 45:41.930
LDX und diese Signale, wie man aus der Bezeichnung hier erkennt, sind

45:41.930 --> 45:43.050
alle Active Flow.

45:43.050 --> 45:51.050
Das heißt, das Register X kann nur dann geladen werden, wenn dieses

45:51.050 --> 45:55.030
Signal hier aktiv ist, das heißt, wenn hier eine Null anliegt.

45:56.070 --> 46:01.950
Das Gleiche für die Funktionalität des Ladens vom Register A und vom

46:01.950 --> 46:03.110
Register B bzw.

46:03.390 --> 46:04.670
auch vom Register Y.

46:05.970 --> 46:11.510
Zusätzlich hat diese Schaltung hier, die man sieht, sogenannte Trieste

46:11.510 --> 46:12.190
Treiber.

46:13.750 --> 46:20.630
Und diese Trieste Treiber sind eine Gatterform, die im Gegensatz zu

46:20.630 --> 46:24.850
allem, was wir bis jetzt kennengelernt haben, nicht zwei Zustände

46:24.850 --> 46:28.090
haben, sondern, wie der Name sagt, drei Zustände.

46:28.090 --> 46:33.470
Das heißt, ein Low, ein High und einen dritten hochohmigen Zustand.

46:34.170 --> 46:40.150
Das heißt, die dienen eigentlich dazu, in Rechnungssystemen mehrere

46:40.150 --> 46:44.310
Komponenten an Bussystemen anzukoppeln.

46:44.310 --> 46:48.970
Also, ihr seid ja Informatiker, das heißt, wir können das nicht

46:48.970 --> 46:52.570
verschweigen oder ich kann euch doch erzählen, dass wir hier ein

46:52.570 --> 46:56.550
Rechnungssystem haben mit einem Mikroprozessor, Hauptspeicher.

46:58.430 --> 46:59.710
Was nehmen wir noch?

47:01.230 --> 47:02.410
DMA-Controller.

47:02.410 --> 47:05.290
Und wir haben einen Bus hier.

47:06.530 --> 47:08.050
Naja, ein bisschen tiefer.

47:12.930 --> 47:21.770
Wir haben einen Bus hier und alle diese Komponenten greifen auf den

47:21.770 --> 47:24.070
Bus oder sind irgendwie mit dem Bus verbunden.

47:24.710 --> 47:28.570
Es gibt eine Besonderheit bei Menschenkomponenten im Rechnungssystem,

47:28.830 --> 47:30.770
die können ja Busmaster werden.

47:31.350 --> 47:37.030
Zum Beispiel der Mikroprozessor, der ist ja der größte Busmaster, aber

47:37.030 --> 47:41.270
ein DMA-Controller kann auch exklusiv auf den Bus zugreifen und

47:41.270 --> 47:45.150
Operationen dort ausführen, ohne Beteiligung des Mikroprozessors.

47:45.150 --> 47:49.410
Diese Themen werden wir noch behandeln, aber in dem Fall jetzt, wenn

47:49.410 --> 47:57.930
der DMA-Controller beispielsweise den Zugriff auf den Bus hat, dann

47:57.930 --> 48:02.830
muss ja der Mikroprozessor seine Ausgänge praktisch von dem Bus

48:02.830 --> 48:04.950
abkoppeln oder abtrennen.

48:04.950 --> 48:09.270
Und das macht man natürlich nicht so, indem man die schneidet, sondern

48:09.270 --> 48:14.090
man hat diese Gatterform, diese Tristetreiber, man versetzt sie in

48:14.090 --> 48:19.470
einem hochohmigen Zustand, sodass praktisch nichts hier vom Inneren

48:19.470 --> 48:23.410
des Prozessors zur Außenwelt kommt, beziehungsweise auch nichts von

48:23.410 --> 48:29.410
der Außenwelt in das Innere, sodass praktisch hier diese Operation in

48:29.410 --> 48:33.370
aller Ruhe ohne Kurzschlüsse, ohne irgendwelche Probleme ausgeführt

48:33.370 --> 48:33.910
werden kann.

48:34.910 --> 48:39.810
Das heißt, was wir jetzt hier wollen, mit Hilfe von dieser Schaltung,

48:40.610 --> 48:45.890
sind die Mikroprogramme zur Ausführung von der Addition der Inhalte

48:45.890 --> 48:53.990
der Register X und Y, der Subtraktion, das Logische Und, Oder und eine

48:53.990 --> 48:58.670
Transfer -Operation, das heißt so etwas wie Transferiere den Inhalt

48:58.670 --> 49:04.490
von X nach Y oder Move X zu Y.

49:05.510 --> 49:12.450
Okay, hier nochmal kurz die Definition von diesen Tristetreibern, das

49:12.450 --> 49:16.690
werden wir noch genauer erklären oder kommt nochmal in der Vorlesung

49:16.690 --> 49:17.030
vor.

49:17.470 --> 49:22.170
Das heißt, das ist eine Gatterform, die neben den Pegelzuständen High

49:22.170 --> 49:26.170
und Low einen dritten hochohmigen Zustand besitzt.

49:26.170 --> 49:31.350
Und in diesem Zustand ist der Ausgang hochohmig, das heißt es kommt

49:31.350 --> 49:33.390
nichts an vom Eingang am Ausgang.

49:34.090 --> 49:39.130
Wenn das Ganze in diesem aktiven Zustand, in diesem hochohmigen

49:39.130 --> 49:45.170
Zustand ist oder sind diese Gatter nicht in dem hochohmigen Zustand,

49:45.350 --> 49:49.410
dann wird alles, was an den Eingang anliegt, direkt an den Ausgang

49:49.410 --> 49:50.170
übertragen.

49:50.170 --> 49:54.510
Das heißt ein Low-Pegel erscheint als Low-Pegel, ein High-Pegel als

49:54.510 --> 49:55.170
High -Pegel.

49:55.930 --> 50:01.350
Und sie dienen durch Ausgangstreiber zur elektrischen Anpassung von z

50:01.350 --> 50:01.630
.B.

50:02.270 --> 50:04.930
Prozessorsignalen an Signalspezifikationen, die von anderen

50:04.930 --> 50:09.070
Systemkomponenten verlangt oder notwendig sind.

50:09.070 --> 50:15.650
Die Funktionsstabelle hier zu, das heißt wenn der Eingang hier Low

50:15.650 --> 50:21.430
ist, ist dieses Gatter in dem hochohmigen Zustand.

50:22.330 --> 50:28.830
Wenn der Eingang High ist, dann ist es praktisch wie verbunden, das

50:28.830 --> 50:32.430
heißt ein Low am Eingang erscheint am Ausgang bzw.

50:32.750 --> 50:36.730
ein High am Eingang erscheint auch am Ausgang.

50:37.670 --> 50:43.230
Die trifft man, wie gesagt, in der System-Bus-Schnittstelle bei

50:43.230 --> 50:44.270
Mikroprozessoren.

50:44.830 --> 50:49.670
Das heißt hier ist es notwendig, sowohl Steuerleitungen abzukoppeln

50:49.670 --> 50:54.350
vom Bus, Adressleitungen als auch Datenleitungen.

50:55.510 --> 51:02.170
Und bei Datenleitungen ist es so, dass Daten sowohl vom Prozessor in

51:02.170 --> 51:04.830
seine Außenwelt fließen als auch umgekehrt.

51:04.830 --> 51:10.970
Das heißt hier braucht man sogenannte bidirektionale 3D-Treiber, die

51:10.970 --> 51:12.210
das auch ermöglichen.

51:12.290 --> 51:17.810
Das heißt, die sowohl einen Datentransfer in die Richtung erlauben als

51:17.810 --> 51:23.770
auch in die Richtung und weiterhin nochmal diesen hochohmigen Zustand

51:23.770 --> 51:26.730
für beide Richtungen realisieren bzw.

51:26.970 --> 51:27.430
erlauben.

51:28.050 --> 51:32.390
Für die Informatiker ist es vielleicht hier nicht schlecht, das haben

51:32.390 --> 51:37.330
wir ja das letzte Semester in Tier 1 behandelt, wie man solche 3D-Data

51:37.330 --> 51:41.010
mithilfe von CMOS-Technologie realisieren kann.

51:42.910 --> 51:48.410
Zurück zu unserer Aufgabe, das heißt wir wollen ja einige Operationen,

51:48.470 --> 51:52.310
die Mikroprogramme zur Ausführung von Operationen mithilfe von dieser

51:52.310 --> 51:53.590
Schaltung hier angeben.

51:53.590 --> 52:00.030
Und die Operationen 1 bis 4, die waren Addition, Subtraktion,

52:00.170 --> 52:01.950
Logisches und Logisches Oder.

52:02.630 --> 52:10.010
Das heißt, eigentlich werden diese Operationen so ausgeführt, dass die

52:10.010 --> 52:14.790
Inhalte der Register X und Y in die Eingangsregister der ALU

52:14.790 --> 52:15.990
transferiert werden.

52:15.990 --> 52:20.110
Und dann die Steuersignale der ALU auf die entsprechenden Werte

52:20.110 --> 52:24.270
gesetzt, anschließend wird das Ergebnis berechnet und im Zielregister

52:24.270 --> 52:26.030
Y abgelegt.

52:27.030 --> 52:34.650
Das heißt, man muss zunächst mal X auf den Bus legen, dazu muss man

52:34.650 --> 52:38.630
natürlich alle weiteren Komponenten vom Bus abkoppeln.

52:39.510 --> 52:46.450
Und hier durch eine entsprechende Belegung dieses Signals hier, das

52:46.450 --> 52:52.950
heißt es muss ja aktiv werden, muss X auf den Bus gelegt werden und so

52:52.950 --> 52:56.210
lange gewartet werden, bis die Daten natürlich stabil auf dem Bus

52:56.210 --> 53:01.970
anliegen, sodass das Register L-A drauf zugreifen kann und D laden

53:01.970 --> 53:02.310
kann.

53:02.310 --> 53:08.390
Das kann man realisieren, also dass das Laden beginnen kann mit Hilfe

53:08.390 --> 53:11.610
von dem Steuersignal Load Register A.

53:12.610 --> 53:16.490
Anschließend Y auf den Bus legen, warten bis die Daten stabil

53:16.490 --> 53:21.330
anliegen, anschließend Y in das Register B laden.

53:23.370 --> 53:30.130
Wenn beide Inhalte hier in den Eingangregistern stabil sind oder

53:30.130 --> 53:35.090
stabil anliegen, werden die Steuersignale hier entsprechend gesetzt,

53:35.190 --> 53:40.750
dass die Operation, Addition oder Subtraktion ausgeführt wird und das

53:40.750 --> 53:46.230
Ergebnis wird dann hier auf dem Bus liegen und kann dann in das

53:46.230 --> 53:48.090
Zielregister X bzw.

53:48.310 --> 53:50.510
Y wieder geleitet werden.

53:50.510 --> 53:53.650
Ja, das ist ja die Vorgehensweise.

53:54.250 --> 53:56.650
Wie sehen die Mikroprogramme aus hierzu?

53:58.010 --> 54:00.830
Ja, die Mikroprogramme, das heißt wir müssen uns darüber Gedanken

54:00.830 --> 54:07.670
machen, welche Werte die entsprechenden Signale LDX, EAX, LDY und so

54:07.670 --> 54:10.350
weiter und so fort haben.

54:10.350 --> 54:15.470
Das ist hier eine mögliche Variante der Lösung, die ich hier angebe.

54:16.050 --> 54:20.070
Das heißt man kann sich über einiges streiten, ob man jetzt die Daten

54:20.070 --> 54:24.850
auf den Bus legt und dann wartet und dann irgendwann mal die ALU auf

54:24.850 --> 54:29.030
Addition oder Subtraktion schaltet.

54:29.030 --> 54:35.590
Das heißt hier im ersten Schritt wollen wir den Inhalt von X auf den

54:35.590 --> 54:40.170
Bus legen, das heißt das müssen wir aktivieren, alles andere muss

54:40.170 --> 54:46.510
deaktiviert sein und die Steuersignale der ALU hier sind noch

54:46.510 --> 54:47.490
uninteressant.

54:47.490 --> 54:50.470
Das heißt die geben ein, welche Operation die ALU ausführt.

54:51.290 --> 55:00.390
Im zweiten Takt holen wir die Daten, die jetzt schon auf dem Bus

55:00.390 --> 55:05.490
stabil anliegen in das Register A, das heißt wir aktivieren das Signal

55:05.490 --> 55:14.490
LDA und nach wie vor müssen die Daten halt stabil auf dem Bus sein,

55:14.610 --> 55:16.590
deshalb EAX immer noch auf 0.

55:18.390 --> 55:22.710
Dann Y auf den Bus legen, das heißt das muss ja 0 sein.

55:23.690 --> 55:28.510
Anschließend Y in das Register hier laden und die ALU auf Addition

55:28.510 --> 55:33.530
schalten, indem man die Kontrollsignale der ALU auf 0,0 setzt.

55:33.530 --> 55:38.550
Hier wird das Ergebnis berechnet, das heißt das Ergebnis wird hier auf

55:38.550 --> 55:42.110
den Bus gelegt, alles andere ist vom Bus abgekoppelt.

55:42.210 --> 55:46.810
Das heißt hier dieses Signal muss auf 0 sein, die ALU weiterhin auf

55:46.810 --> 55:51.810
Addition, damit das Ergebnis nach wie vor stabil bleibt und auf dem

55:51.810 --> 55:53.330
Bus anliegt.

55:53.330 --> 55:58.170
Anschließend lädt man das Ergebnis in das Zielregister, das heißt LDX

55:58.170 --> 56:04.870
muss 0 sein und natürlich auch der Steuereingang von diesem Tristate

56:04.870 --> 56:07.730
Treiber muss auch weiterhin aktiv sein.

56:09.310 --> 56:14.810
Damit hat man eigentlich die Addition X ist gleich, X plus Y

56:14.810 --> 56:15.670
realisiert.

56:16.850 --> 56:24.470
Die Vorgehensweise ist die gleiche für die Subtraktion, bei der

56:24.470 --> 56:30.030
Subtraktion muss man nur andere Steuersignale für die ALU anlegen,

56:30.210 --> 56:34.570
wenn die beiden Operanten stabil in den Eingangsregistern der ALU

56:34.570 --> 56:34.850
sind.

56:34.850 --> 56:41.590
Das heißt bei der Subtraktion war es eingegeben, dass diese

56:41.590 --> 56:48.230
Kombination ist 0,1, beim logischen UND ist es ja eine 1,0 und beim

56:48.230 --> 56:50.410
ODER ist es eine 1,1.

56:51.230 --> 56:53.170
So, jetzt zu den Fragen.

56:54.470 --> 56:54.770
Warum?

57:01.690 --> 57:08.550
In der zweitletzten Spalte, das ist für mich die hier, also vorletzte

57:08.550 --> 57:13.290
Spalte und dann das

57:16.670 --> 57:19.370
EAY muss auf 1 sein.

57:35.000 --> 57:36.360
Ja, Entschuldigung.

57:37.160 --> 57:40.340
Also das EAY muss definitiv 1 sein.

57:42.200 --> 57:42.880
Danke.

57:43.780 --> 57:49.920
Und das ist ja erstaunlich, ich habe es nicht erwartet, dass noch

57:49.920 --> 57:50.820
jemand mitdenkt.

57:51.200 --> 57:55.550
Alle Achtung.

57:56.130 --> 57:56.910
Noch was?

57:58.990 --> 58:05.490
So, die fünfte Operation, die wir ausführen wollen, war ja Move X zu

58:05.490 --> 58:05.790
Y.

58:06.570 --> 58:10.090
Das heißt eigentlich, wir brauchen hier nichts anderes als X auf den

58:10.090 --> 58:14.870
Bus zu legen und anschließend in das Register Y zu laden.

58:14.870 --> 58:20.210
Das heißt anschließend Y laden und wenn wir hier die Kombinationen der

58:20.210 --> 58:24.210
Signale betrachten, X auf den Bus legen, das heißt 0 und der Rest 1

58:24.210 --> 58:28.290
und dann anschließend müssen wir das in das Register hier laden, das

58:28.290 --> 58:30.510
heißt LDY muss auch 0 sein.

58:30.990 --> 58:31.350
Stimmt?

58:32.350 --> 58:40.390
So, somit haben wir praktisch diese Transfer-Operation realisiert.

58:42.350 --> 58:43.870
Soviel zu dem Thema.

58:44.030 --> 58:49.270
Wir lassen es bei diesem Thema Mikroprogrammierung im Moment dabei.

58:49.870 --> 58:55.290
Wir werden auf das Thema nochmal zu sprechen kommen und zwar, wenn wir

58:55.290 --> 59:01.230
den Aufbau von Steuerwerken in Mikroprozessoren betrachten und zwar in

59:01.230 --> 59:06.890
mikroprogrammierte Steuerwerke bei Mikroprozessoren.

59:06.890 --> 59:13.970
Da werden wir halt sehen, dass wir dort nichts anderes als derartige

59:13.970 --> 59:18.330
Mikroprogramme haben, die zur Ausführung von einem Add, von einem

59:18.330 --> 59:21.870
Move, von einem Verzweigungsbefehl usw.

59:22.070 --> 59:22.490
usf.

59:23.070 --> 59:27.270
abgelegt werden und wenn der entsprechende Befehl ausgeführt werden

59:27.270 --> 59:32.510
soll, dann muss ja dieses Mikroprogramm ausgeführt werden, indem

59:32.510 --> 59:36.830
Steuersignale für bestimmte Komponenten im Prozessor aktiviert werden.

59:39.670 --> 59:42.030
So, zum zweiten Thema.

59:42.210 --> 59:47.670
Nun kommen wir zum zweiten Thema der heutigen Übung und zwar, wir

59:47.670 --> 59:52.770
wollen ja uns mit der Assemblerprogrammierung im Rahmen der

59:52.770 --> 59:54.790
Technischen Informatik II beschäftigen.

59:57.110 --> 01:00:01.190
Das ist für viele von euch sehr abschreckend, das kann ich verstehen.

01:00:01.370 --> 01:00:06.930
Das ging mir auch genauso, als ich studiert habe und Assembler lernen

01:00:06.930 --> 01:00:07.310
musste.

01:00:08.390 --> 01:00:11.630
Aber das hat ja wesentliche Vorteile.

01:00:13.170 --> 01:00:17.390
Auf der einen Seite versteht man einiges über die Funktionsweise von

01:00:17.390 --> 01:00:21.810
Prozessoren, wenn man weiß, wie überhaupt diese Prozessoren oder diese

01:00:21.810 --> 01:00:27.110
Mikroregionalsysteme auf Maschinennaherebene programmiert werden.

01:00:28.190 --> 01:00:34.270
Das Ganze ist sehr fehleranfällig und umständlich und kompliziert und

01:00:34.270 --> 01:00:36.290
schwierig, das ist uns allen bekannt.

01:00:37.250 --> 01:00:45.310
Aber wir wollen hier nur verstehen, wie überhaupt unsere Programme,

01:00:45.390 --> 01:00:49.230
die zunächst einmal in einer höheren Programmiersprache geschrieben

01:00:49.230 --> 01:00:55.830
werden, auf bestimmte Rechnerhardware abgebildet sind bzw.

01:00:56.310 --> 01:01:00.590
durch beliebige Rechnerhardware ausgeführt werden können, wenn die

01:01:00.590 --> 01:01:03.330
entsprechenden Compiler und Übersetzer usw.

01:01:04.210 --> 01:01:05.530
hierzu vorhanden sind.

01:01:05.530 --> 01:01:13.590
Ich will das Ganze heute nur einführen und auf diese symbolische und

01:01:13.590 --> 01:01:16.890
Maschinencode -Darstellung von Programmen eingehen.

01:01:19.030 --> 01:01:22.470
Anschließend, wenn die Zeit reicht, werde ich kurz zur

01:01:22.470 --> 01:01:24.090
Programmübersetzung, d.h.

01:01:24.210 --> 01:01:28.970
zur Übersetzung von in Assemblersprache geschriebenen Programmen, hier

01:01:28.970 --> 01:01:29.910
etwas erzählen.

01:01:29.910 --> 01:01:36.790
Und natürlich wie bei jeder Hochprogrammiersprache oder wie bei jeder

01:01:36.790 --> 01:01:41.850
Sprache der höheren Programmiersprachen, hat jede Assemblersprache

01:01:41.850 --> 01:01:43.190
ihren Syntax.

01:01:43.190 --> 01:01:46.750
Mit dem Unterschied, dass Assemblersprachen natürlich

01:01:46.750 --> 01:01:51.330
maschinenspezifisch sind im Gegensatz zu Hochprogrammiersprachen, d.h.

01:01:51.990 --> 01:01:58.330
die Assembler von Intel unterscheiden sich von der von MIPS

01:01:58.330 --> 01:01:59.630
Prozessoren bzw.

01:01:59.990 --> 01:02:03.830
von Macintosh, also von Apple usw.

01:02:03.830 --> 01:02:05.150
D.h.

01:02:05.310 --> 01:02:08.310
wenn man Assembler programmiert, muss man immer wieder eine neue

01:02:08.310 --> 01:02:10.870
Assembler, weil man neue Hardware hat.

01:02:11.290 --> 01:02:13.550
Das ist natürlich der Vorteil, den man durch höhere

01:02:13.550 --> 01:02:14.850
Programmiersprachen hat.

01:02:15.270 --> 01:02:19.090
Man programmiert in Java, das Ganze läuft auf allen Plattformen.

01:02:19.150 --> 01:02:23.830
Man programmiert in C, das Ganze läuft auch auf allen Plattformen.

01:02:25.150 --> 01:02:30.250
So, wir wollen hier kurz die Begriffe hier, die wurden ja in der

01:02:30.250 --> 01:02:35.050
Vorlesung erwähnt, hier sind sie nochmal zur Wiederholung angegeben.

01:02:35.670 --> 01:02:39.870
Also eine Maschinensprache ist eine Repräsentation von Programmen bzw.

01:02:40.150 --> 01:02:44.690
von Anweisungen, die für einen Mikroprozessor direkt verständlich

01:02:44.690 --> 01:02:44.990
sind.

01:02:44.990 --> 01:02:49.210
Und die Assemblersprache ist eine symbolische Repräsentation der

01:02:49.210 --> 01:02:53.490
Maschinensprache, die für uns Menschen verständlicher und

01:02:53.490 --> 01:02:54.630
anschaulicher ist.

01:02:54.630 --> 01:02:58.170
Wenn man hier sieht, das ist nichts anderes als, ich addiere den

01:02:58.170 --> 01:03:03.110
Inhalt vom Register R1 zu R2 und schreibe das Ergebnis in R1.

01:03:03.690 --> 01:03:10.550
Im Maschinencode ist das angegeben durch diese Bitfolge.

01:03:11.230 --> 01:03:14.890
In der Assemblersprache könnte das so aussehen.

01:03:14.890 --> 01:03:21.790
Das heißt, man gibt zwei Quellregister, in denen die beiden Operanten

01:03:21.790 --> 01:03:26.430
der Operation abgelegt sind und ein Zielregister, in dem das Ergebnis

01:03:26.430 --> 01:03:28.370
gespeichert werden soll.

01:03:29.930 --> 01:03:33.130
Ich will das Ganze einführen anhand von einer kleinen

01:03:33.130 --> 01:03:34.310
Programmieraufgabe.

01:03:34.550 --> 01:03:40.290
Und zwar, wir wollen mit Hilfe von einem Mikroprozessor-System einen

01:03:40.290 --> 01:03:43.030
Impulsgeber realisieren.

01:03:43.030 --> 01:03:48.730
Und zwar, dieser Impulsgeber soll in konstanten Zeitabständen Impulse

01:03:48.730 --> 01:03:55.810
an eine Ausgabeeinheit, also an eine Peripherieeinheit abgeben.

01:03:56.430 --> 01:04:00.430
Zur Lösung dieser Aufgabe wollen wir einen Satz von Befehlen

01:04:00.430 --> 01:04:04.310
festlegen, genauso wie bei der ersten Aufgabe, aber auf der

01:04:04.310 --> 01:04:05.230
Assemblerebene.

01:04:06.070 --> 01:04:10.650
Und dann wollen wir aus diesem Satz, also aus diesen Befehlen, die wir

01:04:10.650 --> 01:04:14.910
definieren, die notwendig sind zur Lösung dieser Aufgabe, wollen wir

01:04:14.910 --> 01:04:20.170
zunächst mal natürlich das Programm in Assembler-Code angeben.

01:04:20.990 --> 01:04:24.490
Das heißt, wir haben ja unsere eigene Assembler hier festgelegt, weil

01:04:24.490 --> 01:04:26.970
wir ja die Maschinenbefehle selber definiert haben.

01:04:26.970 --> 01:04:30.970
Normalerweise ist das durch den Prozessor oder den Prozessorhersteller

01:04:30.970 --> 01:04:35.230
fest vorgegeben, welche Maschinenbefehle welcher Prozessor ausführen

01:04:35.230 --> 01:04:35.550
kann.

01:04:36.410 --> 01:04:41.610
Und anschließend, wenn die Zeit heute noch reicht, werden wir das von

01:04:41.610 --> 01:04:46.990
uns in Assembler geschriebene Programm per Hand in Maschinen-Code

01:04:46.990 --> 01:04:47.650
umsetzen.

01:04:50.970 --> 01:04:57.490
Und anschließend, der zweite Teil ist eigentlich, wie das heutzutage

01:04:57.490 --> 01:04:58.350
gemacht wird.

01:04:58.850 --> 01:05:02.170
Wie das heutzutage gemacht wird, nicht in dem Sinne, dass man

01:05:02.170 --> 01:05:07.690
heutzutage nur in Java programmiert, sondern wie das bei

01:05:07.690 --> 01:05:11.990
Mikroprozessoren gemacht wird, wo man in Assembler programmiert.

01:05:11.990 --> 01:05:16.310
Es ist natürlich unvorstellbar, dass man die Assembler-Programmie per

01:05:16.310 --> 01:05:21.630
Hand sozusagen in Maschinen-Code umsetzt, sondern es gibt bestimmt

01:05:21.630 --> 01:05:25.530
hierzu Tools und Programmie, die das leisten.

01:05:26.930 --> 01:05:31.270
Das heißt, wir betrachten hier ein Mikroprozessor-System, bestehend

01:05:31.270 --> 01:05:36.510
aus einem Mikroprozessor mit einem Textsignal, eine Speichereinheit

01:05:36.510 --> 01:05:42.370
und eine Eingabe-Ausgabe-Einheit.

01:05:42.510 --> 01:05:48.430
Diese Eingabe-Ausgabe-Einheit hat ja einen Interface-Baustein mit

01:05:48.430 --> 01:05:52.370
einem 16-Bit-breiten Datenregister.

01:05:53.490 --> 01:05:57.450
Das Datenregister ist hier mit Eingabe-Ausgabe-Register

01:05:57.450 --> 01:05:58.450
gekennzeichnet.

01:05:59.150 --> 01:06:05.230
Und wir wollen praktisch hier jetzt ein Programm schreiben, sodass wir

01:06:05.230 --> 01:06:08.550
diese Impulsfolge realisieren.

01:06:08.670 --> 01:06:12.070
Das heißt, diese Impulsfolge soll jetzt an diese Eingabe-Ausgabe

01:06:12.070 --> 01:06:14.390
-Einheit weitergeleitet werden.

01:06:14.830 --> 01:06:21.730
Das heißt, eine Impulsfolge der Periode von T und diese Einheit

01:06:21.730 --> 01:06:25.690
verfügt nur über einen Interface-Register, also über einen Eingabe

01:06:25.690 --> 01:06:27.690
-Ausgabe -Register der Breite 16-Bit.

01:06:28.770 --> 01:06:30.470
Das bezeichnen wir mit so und so.

01:06:30.610 --> 01:06:34.350
Die absolute Adresse von diesem Register hier ist durch die

01:06:34.350 --> 01:06:38.370
Adressdekodierung von diesem Interface-Baustein normalerweise fest

01:06:38.370 --> 01:06:39.070
vorgegeben.

01:06:39.730 --> 01:06:41.210
Und die hat den Wert 8000.

01:06:42.690 --> 01:06:48.390
Die Schreibweise oder die Schreibweise bedeutet für uns immer Zahlen

01:06:48.390 --> 01:06:50.550
in hexadezimaler Form.

01:06:50.550 --> 01:06:55.530
Das heißt, das ist 8000 hexadezimal, das ist auch 8000 hexadezimal.

01:06:56.110 --> 01:06:58.870
Die Periodendauer der Impulsfolge soll ja T sein.

01:06:59.650 --> 01:07:02.110
So, wie löst man diese Aufgabe?

01:07:03.750 --> 01:07:09.930
Zunächst mal, diese Periodendauer soll ja von der Eingabe-Ausgabe

01:07:09.930 --> 01:07:12.230
-Einheit bereitgestellt werden.

01:07:12.410 --> 01:07:16.450
Das heißt, zunächst mal wird die Periodendauer vorgegeben.

01:07:16.450 --> 01:07:21.010
Diese Periodendauer wird vom Mikrorechner eingelesen.

01:07:21.670 --> 01:07:28.930
Und anschließend soll ja unser Programm eigentlich diese Impulsfolge

01:07:28.930 --> 01:07:29.530
generieren.

01:07:29.650 --> 01:07:33.370
Diese Impulsfolge können wir so generieren, indem wir eigentlich

01:07:33.370 --> 01:07:39.010
dieses Nur generieren, indem wir das Register hier mit 0 oder mit 1

01:07:39.010 --> 01:07:39.670
überschreiben.

01:07:40.130 --> 01:07:44.010
Das heißt, wenn wir hier ein 0 haben, dann haben wir sowas ähnliches

01:07:44.010 --> 01:07:44.690
wie das hier.

01:07:44.690 --> 01:07:48.850
Wenn wir eine 1 hier einschreiben, dann haben wir praktisch diesen

01:07:48.850 --> 01:07:49.370
Impuls.

01:07:50.930 --> 01:07:57.510
So, das heißt hierzu wird jetzt diese Zeitkonstante, die praktisch

01:07:57.510 --> 01:08:03.410
auch irgendwie die Periodendauer beschreibt, in den Speicher gelesen

01:08:03.410 --> 01:08:10.730
und anschließend wird in das Register hier solange Nulling

01:08:10.730 --> 01:08:15.890
geschrieben, bis jetzt die Periodendauer erreicht ist, dann wird eine

01:08:15.890 --> 01:08:20.610
1 in das Register hier übertragen bzw.

01:08:21.130 --> 01:08:25.550
geschrieben für die Dauer von einem einzigen Befehl und anschließend

01:08:25.550 --> 01:08:26.410
wiederum eine Null.

01:08:28.410 --> 01:08:30.990
Haben wir das verstanden, wie das funktionieren soll?

01:08:33.790 --> 01:08:38.290
So, das Ganze ist hier mit Hilfe von einem Flussdiagramm vielleicht

01:08:38.290 --> 01:08:39.950
noch besser verständlicher.

01:08:39.950 --> 01:08:45.630
Das heißt, diese Zeitkonstante, die von der Eingabe-Ausgabe-Einheit

01:08:45.630 --> 01:08:52.150
entnimmt, der Mikroprozessor aus dem Register EA dieser Eingabe

01:08:52.150 --> 01:08:53.190
-Ausgabe -Einheit.

01:08:54.950 --> 01:09:01.130
Das Eingabe-Ausgabe-Einheit initialisiert man zunächst mal mit 0 und

01:09:01.130 --> 01:09:05.150
irgendwann mal initialisiert man das für die Dauer von einem einzigen

01:09:05.150 --> 01:09:10.670
Befehl mit 1, damit man diesen Impuls, also diesen Peak hier hat und

01:09:10.670 --> 01:09:12.190
anschließend mit 0.

01:09:13.110 --> 01:09:16.570
So, wir wollen aber nicht nur einen einzigen Impuls ausgeben, sondern

01:09:16.570 --> 01:09:18.890
wir wollen eine Folge von Impulsen ausgeben.

01:09:19.050 --> 01:09:23.270
Hierzu muss man natürlich bestimmte Teile von dem Programm wiederholt

01:09:23.270 --> 01:09:23.810
ausführen.

01:09:24.030 --> 01:09:27.210
Das heißt, in der Informatiksprache, man bildet eine sogenannte

01:09:27.210 --> 01:09:27.770
Schleife.

01:09:27.770 --> 01:09:34.330
Und da wir diese Impulse unendlich lang hier bilden, also immer

01:09:34.330 --> 01:09:39.130
kontinuierlich haben werden, sieht man hier, dass wir immer in diesem

01:09:39.130 --> 01:09:43.050
Flussdiagramm zu der Stelle hier kommen, irgendwelche Vergleiche hier

01:09:43.050 --> 01:09:47.170
ausführen und anschließend einen Impuls ausgeben, dann wiederum alles

01:09:47.170 --> 01:09:49.450
auf 0 zurücksetzen und so weiter und so fort.

01:09:49.930 --> 01:09:58.810
Die Dauer dieser Impulse hier, T, hängt natürlich davon ab, wie oft

01:09:58.810 --> 01:10:05.170
diese innere Schleife durchlaufen wird.

01:10:08.940 --> 01:10:15.100
Das heißt, wenn wir jetzt dieses Flussdiagramm betrachten, dann sehen

01:10:15.100 --> 01:10:20.200
wir, dass wir eigentlich hier auch wiederum typische Befehle brauchen,

01:10:20.440 --> 01:10:22.720
um diese Operationen auszuführen.

01:10:23.540 --> 01:10:29.660
Das heißt, wir brauchen Befehle wie move das hier zu dem hier,

01:10:32.280 --> 01:10:36.680
beziehungsweise wir brauchen ein Befehl zum Vergleichen von einem Wert

01:10:36.680 --> 01:10:37.220
auf 0.

01:10:37.220 --> 01:10:41.140
Das heißt, hier diese Zeitkonstante schreiben wir in einem Register,

01:10:41.300 --> 01:10:46.740
von mir aus eine temporäre Variable und die dekrementieren wir immer

01:10:46.740 --> 01:10:48.020
bei jedem Durchlauf.

01:10:48.520 --> 01:10:52.400
Wenn das bei 0 gelandet ist, dann ist die Periodendauer erreicht und

01:10:52.400 --> 01:10:56.900
anschließend, das heißt, in dem Fall muss jetzt ein Impuls ausgegeben

01:10:56.900 --> 01:10:58.420
werden und so weiter und so fort.

01:10:58.980 --> 01:11:03.180
Das heißt, wir brauchen irgendetwas wie ein Dekrementierbefehl oder

01:11:03.180 --> 01:11:09.680
ein Subtraktionsbefehl, ein Befehl zur bedingten Verzweigung.

01:11:09.920 --> 01:11:15.280
Das heißt, wenn die Variable R2, was bei einem Mikroprozessor ein

01:11:15.280 --> 01:11:21.660
Register ist, wenn das den Wert 0 hat, dann soll einmal das Register

01:11:21.660 --> 01:11:26.540
EA mit 1 initialisiert werden oder eine 1 dort geschrieben werden,

01:11:26.640 --> 01:11:27.760
anschließend eine 0.

01:11:28.260 --> 01:11:32.060
Wenn nicht, dann soll diese Streife wiederholt durchlaufen werden, bis

01:11:32.060 --> 01:11:32.940
das hier auftritt.

01:11:33.640 --> 01:11:37.980
So, das heißt, die Befehle, die wir hier brauchen, die notwendigen

01:11:37.980 --> 01:11:42.860
Befehle, sind so etwas wie MOV, Quellregisterinhalt zu einem

01:11:42.860 --> 01:11:50.360
Zielregister, also MOV-Inhalt von QADR nach ZADR, ein

01:11:50.360 --> 01:11:57.700
Subtrahierbefehl, Subtrahier-Inhalt von einem Register zu dem anderen

01:11:57.700 --> 01:11:58.360
bzw.

01:11:59.520 --> 01:12:02.220
ein Operanten 1 von einem Register.

01:12:02.400 --> 01:12:07.120
Das ist notwendig, um beispielsweise diese Subtraktion hier oder

01:12:07.120 --> 01:12:12.480
diesen Deinkrementiervorgang oder Deinkrementieroperation auszuführen.

01:12:12.960 --> 01:12:21.180
Dann brauchen wir ein Vergleichsbefehl, der zwei Variablen bzw.

01:12:22.280 --> 01:12:27.480
zwei Register miteinander vergleicht und auf Gleichheit, das heißt

01:12:27.480 --> 01:12:34.660
hier mit Hilfe von etwas wie COMPARE Register 1 und Register 2 werden

01:12:34.660 --> 01:12:39.660
diese Operanten miteinander verglichen und eine Aussage darüber, ob

01:12:39.660 --> 01:12:43.300
die gleich sind oder ungleich sind, natürlich irgendwo im

01:12:43.300 --> 01:12:44.760
Mikroprozessor abgelegt.

01:12:44.860 --> 01:12:49.780
Wir werden sehen, dass diese Information in den CC-Bits vom

01:12:49.780 --> 01:12:52.520
Statusregister des Prozessors abgelegt wird.

01:12:53.840 --> 01:12:58.260
Und anschließend brauchen wir natürlich ein Befehl zum bedingten

01:12:58.260 --> 01:13:03.340
Sprung, das heißt, wenn die Operation, wenn dieser Vergleich negativ

01:13:03.340 --> 01:13:07.540
ausfällt, dann wollen wir ja hier zu der Stelle springen, ansonsten

01:13:07.540 --> 01:13:08.180
weitermachen.

01:13:08.300 --> 01:13:13.880
Das heißt, wir brauchen einen Befehl zum bedingten Sprung, also der

01:13:13.880 --> 01:13:20.020
Befehlszähler wird mit der Sprungadresse geladen, wenn bei einem

01:13:20.020 --> 01:13:27.220
vorhergehenden Vergleich die Situation oder der Zustand ungleich war.

01:13:28.100 --> 01:13:33.320
Und natürlich brauchen wir hier, damit wir diese Schleife realisieren,

01:13:34.100 --> 01:13:37.860
einen Befehl zum unbedingten Sprung.

01:13:38.000 --> 01:13:41.340
Das heißt, immer wenn wir an der Stelle hier landen, müssen wir

01:13:41.340 --> 01:13:42.900
wiederum hier her springen.

01:13:42.900 --> 01:13:49.140
Das heißt, hier brauchen wir so etwas wie Jump zu einem bestimmten

01:13:49.140 --> 01:13:55.040
Ort, das heißt, ein unbedingter Sprung, in dem Fall würde der

01:13:55.040 --> 01:13:59.660
Befehlszähler des Mikroprozessors mit der eingegebenen Sprungadresse

01:13:59.660 --> 01:14:00.140
geladen.

01:14:01.420 --> 01:14:06.220
So, das heißt, eigentlich können wir jetzt mit Hilfe von diesen

01:14:06.220 --> 01:14:08.460
Befehlen unser Programm hier schreiben.

01:14:08.460 --> 01:14:14.700
Zunächst einmal, das ist das Flussdiagramm hier angegeben.

01:14:15.700 --> 01:14:22.540
Die Zeitkonstante übernimmt der Mikroprozessor aus dem Register EA-REG

01:14:22.540 --> 01:14:25.320
von der Eingabe-Ausgabe-Einheit.

01:14:26.180 --> 01:14:29.780
Dann wird eine Null in dieses Register hier geschrieben.

01:14:32.920 --> 01:14:38.940
Anschließend wird in Erweiterung zu diesem Diagramm hier ein Register,

01:14:39.260 --> 01:14:41.840
eine weitere temporäre Variable R0.

01:14:42.560 --> 01:14:49.320
Das Problem ist, ich kann hier die Wörter Register, Befehlszähler und

01:14:49.320 --> 01:14:52.500
so weiter und so fort nicht offiziell benutzen, weil wir das in der

01:14:52.500 --> 01:14:56.540
Vorlesung dieses Mal noch nicht behandelt haben und wir einen anderen

01:14:56.540 --> 01:14:58.940
Aufbau der Vorlesung hier vorstellen.

01:14:58.940 --> 01:15:03.700
Aber man könnte sich vorstellen, dass diese R0 und R2, wenn man mit

01:15:03.700 --> 01:15:08.600
dem Wort Register eines Prozessors noch nicht so zufrieden oder

01:15:08.600 --> 01:15:12.540
vertraut ist, dass das temporäre Variablen sind, auf die man sehr

01:15:12.540 --> 01:15:13.840
schnell zugreifen kann.

01:15:14.820 --> 01:15:16.700
Also in C-Register-Variablen.

01:15:18.260 --> 01:15:22.260
So, ich sehe, wir sind hier am Ende der Zeit angekommen.

01:15:22.480 --> 01:15:24.160
Wir machen das Ganze hier fertig.

01:15:24.160 --> 01:15:27.560
Ich bedanke mich heute für die Aufmerksamkeit und wünsche euch noch

01:15:27.560 --> 01:15:28.360
einen schönen Tag.

