[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:00.00,0:00:09.70,Default,,0000,0000,0000,,{\i1}32C3 Vorspannmusik{\i0} Dialogue: 0,0:00:09.72,0:00:14.55,Default,,0000,0000,0000,,Herald: Dann ist es mir jetzt eine ganz\Nbesondere Freude Matthias Koch Dialogue: 0,0:00:14.55,0:00:21.20,Default,,0000,0000,0000,,vorzustellen. Der wird über Compiler\NOptimierung für Forth im Microcontroller Dialogue: 0,0:00:21.20,0:00:25.14,Default,,0000,0000,0000,,sprechen. Bitte einen warmen\NApplaus für Matthias. Dialogue: 0,0:00:25.14,0:00:31.27,Default,,0000,0000,0000,,{\i1}Applaus{\i0} Dialogue: 0,0:00:31.27,0:00:35.72,Default,,0000,0000,0000,,Matthias: Guten Tag, Hallo. Wie gesagt\NCompileroptimierung für Forth im Dialogue: 0,0:00:35.72,0:00:40.19,Default,,0000,0000,0000,,Microcontroller und ganz zur Eröffnung\Nhabe ich eine Frage: Wer von euch kennt Dialogue: 0,0:00:40.19,0:00:46.35,Default,,0000,0000,0000,,Forth eigentlich schon? Okay, so etwa die\NHälfte. Das bedeutet aber ich sollte Dialogue: 0,0:00:46.35,0:00:50.48,Default,,0000,0000,0000,,besser noch einmal kurz erklären was\Ndiese Sprache eigentlich ausmacht. Es ist Dialogue: 0,0:00:50.48,0:00:56.06,Default,,0000,0000,0000,,eine Sprache die auf dem Modell eines\NStacks basiert. Vielleicht kennt ihr Dialogue: 0,0:00:56.06,0:01:00.84,Default,,0000,0000,0000,,die umgekehrte polnische Notation wo es so\Nist das erst die Parameter kommen und dann Dialogue: 0,0:01:00.84,0:01:04.21,Default,,0000,0000,0000,,die Operatoren. Man legt also Werte auf\Nden Stack und von oben kommen die Dialogue: 0,0:01:04.21,0:01:08.67,Default,,0000,0000,0000,,Operatoren, nehmen sich ewas und berechnen\Newas und legen es wieder darauf. Es gibt Dialogue: 0,0:01:08.67,0:01:12.64,Default,,0000,0000,0000,,noch einen zweiten Stack, den Return-Stack\Nworüber die Rücksprungadressen Dialogue: 0,0:01:12.64,0:01:17.20,Default,,0000,0000,0000,,gehandhabt werden. Das bedeutet man kann\Nnacheinander die verschiedenen Operatoren Dialogue: 0,0:01:17.20,0:01:22.95,Default,,0000,0000,0000,,aufrufen und muss nicht wie bei C den\NStackframe hin und her kopieren. Der Dialogue: 0,0:01:22.95,0:01:28.12,Default,,0000,0000,0000,,Compiler selbst ist sehr simpel aufgebaut.\NEs basiert darauf, dass man den Eingabestrom Dialogue: 0,0:01:28.12,0:01:34.47,Default,,0000,0000,0000,,was der Mensch tippt, in Wörter zerhackt,\Nalso ein Space, Tabulator, Zeilenumbruch. Dialogue: 0,0:01:34.47,0:01:38.05,Default,,0000,0000,0000,,Wenn ein Wort gefunden wird, wird es in\Nder Liste der bekannten Wörter gesucht Dialogue: 0,0:01:38.05,0:01:42.71,Default,,0000,0000,0000,,entweder ausgeführt oder compiliert und\Nwenn es nicht gefunden werden kann wird es Dialogue: 0,0:01:42.71,0:01:46.74,Default,,0000,0000,0000,,als Zahl interpretiert, auf den Stack\Ngelegt, oder es wird etwas kompiliert um Dialogue: 0,0:01:46.74,0:01:49.95,Default,,0000,0000,0000,,diese Zahl dann später auf den Stack zu\Nlegen. Das war eigentlich schon die Dialogue: 0,0:01:49.95,0:01:54.82,Default,,0000,0000,0000,,Sprache. Das Besondere daran ist, dass\Nsie klein genug ist, dass sie in einem Dialogue: 0,0:01:54.82,0:01:59.45,Default,,0000,0000,0000,,Mikrocontroller installiert werden kann.\NWas dazu führt das man dann mit einem Dialogue: 0,0:01:59.45,0:02:04.38,Default,,0000,0000,0000,,Terminal mit seinem Chip sprechen kann und\Nvon innen heraus ausprobieren, ob der Dialogue: 0,0:02:04.38,0:02:07.78,Default,,0000,0000,0000,,Hardwarecode funktioniert, weil man dann\Nnicht viele kleine Testprogramme schreiben Dialogue: 0,0:02:07.78,0:02:11.80,Default,,0000,0000,0000,,muss, sondern ganz einfach von Hand an den\NLeitungen wackeln kann und alle Dialogue: 0,0:02:11.80,0:02:16.73,Default,,0000,0000,0000,,Definitionen die man geschrieben hat auch\Nsofort interaktiv ausprobieren kann. Das Dialogue: 0,0:02:16.73,0:02:20.22,Default,,0000,0000,0000,,führt dann auch dazu, dass die\NDefinitionen natürlich gleich in der Dialogue: 0,0:02:20.22,0:02:24.64,Default,,0000,0000,0000,,Hardware läuft und auch gleich mit\NEchtzeit, so dass man die Fehlersuche Dialogue: 0,0:02:24.64,0:02:31.78,Default,,0000,0000,0000,,stark vereinfachen kann. Das ist so ein\Nbisschen eine Einführung in Forth. Dialogue: 0,0:02:31.78,0:02:34.64,Default,,0000,0000,0000,,Ich selbst habe diese Sprachen nicht\Nerfunden, die gibt es schon seit mehr als Dialogue: 0,0:02:34.64,0:02:36.29,Default,,0000,0000,0000,,einem halben Jahrhundert. Dialogue: 0,0:02:36.29,0:02:41.22,Default,,0000,0000,0000,,Aber ich habe Compiler geschrieben\Nfür MSP430, ARM Cortex M0, M3 Dialogue: 0,0:02:41.22,0:02:46.91,Default,,0000,0000,0000,,und M4, M7 ist in Planung und es gibt noch\Neine Variante, die in Zusammenarbeit mit dem Dialogue: 0,0:02:46.91,0:02:50.72,Default,,0000,0000,0000,,Bowman gemacht habe, die auf einem\NFPGA läuft. Aber dazu ein bisschen mehr Dialogue: 0,0:02:50.72,0:02:55.20,Default,,0000,0000,0000,,später. Eigentlich ist das ungewöhnlich\Nsich selbst vorzustellen aber meine Dialogue: 0,0:02:55.20,0:02:58.92,Default,,0000,0000,0000,,Freunde meinen das sollte man sagen. Ich\Nbin Diplomphysiker und habe Physik mit Dialogue: 0,0:02:58.92,0:03:03.87,Default,,0000,0000,0000,,Nebenfach Gartenbau studiert, bin gerade in\Nmeiner Doktorarbeit in der Laserspektroskopie Dialogue: 0,0:03:03.87,0:03:08.03,Default,,0000,0000,0000,,habe gemischte Interessen durcheinander, \Nbesonders Radionavigation Dialogue: 0,0:03:08.03,0:03:12.40,Default,,0000,0000,0000,,und meine Lieblingssprachen \Nkann man hier sehen. Dialogue: 0,0:03:12.40,0:03:17.01,Default,,0000,0000,0000,,Der Name mag vielleicht etwas ungewöhnlich\Nsein, aber die erste unterstützte Dialogue: 0,0:03:17.01,0:03:22.55,Default,,0000,0000,0000,,Plattform war der MSP430 von MSP und\N"écris" aus dem französischen kam der Dialogue: 0,0:03:22.55,0:03:26.94,Default,,0000,0000,0000,,Name dann. Überschreibt den MSP430\Nweil es da innen drin ist und man schreibt Dialogue: 0,0:03:26.94,0:03:32.60,Default,,0000,0000,0000,,direkt hinein. Unterstützt dann alle\NMSP430-Launchpads, sehr viele ARM Cortex Dialogue: 0,0:03:32.60,0:03:39.59,Default,,0000,0000,0000,,Architekturen und mit dem FPGA ein\Nbisschen mehr. Die klassischen Dialogue: 0,0:03:39.59,0:03:44.12,Default,,0000,0000,0000,,Architekturen, also die auf denen Forth\Nnormalerweise implementiert worden ist Dialogue: 0,0:03:44.12,0:03:48.02,Default,,0000,0000,0000,,– so geschichtlich – waren eine virtuelle\NMaschine. Wo eine Liste von Pointern Dialogue: 0,0:03:48.02,0:03:52.85,Default,,0000,0000,0000,,drinen war, wo nacheinander diese Pointer\Ngenommen worden sind und dann entweder wie Dialogue: 0,0:03:52.85,0:03:58.56,Default,,0000,0000,0000,,eine Liste von Pointern zählten oder\Naber eben ein Assemblerprimitive. Dialogue: 0,0:03:58.56,0:04:03.49,Default,,0000,0000,0000,,Natürlich ist das sehr schön, wenn man\Ndann Fehler suchen möchte im Compiler, es Dialogue: 0,0:04:03.49,0:04:06.77,Default,,0000,0000,0000,,wird sehr einfach dadurch und es lassen\Nsich auch einige ungewöhnliche Sachen Dialogue: 0,0:04:06.77,0:04:12.99,Default,,0000,0000,0000,,dabei implementieren. Aber es frisst\Nviele viele Taktzyklen. Die ganz alten Dialogue: 0,0:04:12.99,0:04:18.24,Default,,0000,0000,0000,,Systeme hatten sogar die Möglichkeit noch\Neinmal über eine Tabelle die ganzen Dialogue: 0,0:04:18.24,0:04:22.55,Default,,0000,0000,0000,,verschiedenen Pointer umzuleiten, so dass\Nman Definitionen die schon liefen Dialogue: 0,0:04:22.55,0:04:27.04,Default,,0000,0000,0000,,nachträglich noch ändern konnte, also\Neine Definition ganz tief im System durch Dialogue: 0,0:04:27.04,0:04:30.69,Default,,0000,0000,0000,,etwas neues austauschen. Die wird dann\Nsofort auch verwendet. Das ging mal. Dialogue: 0,0:04:30.69,0:04:33.97,Default,,0000,0000,0000,,Ausserdem lässt sich Forth sehr leicht\Ndekompilieren, zumindest bei der Dialogue: 0,0:04:33.97,0:04:39.25,Default,,0000,0000,0000,,klassischen Implementation, so das bei\Neiner Jupiter Ace. Man braucht ja keine Dialogue: 0,0:04:39.25,0:04:43.75,Default,,0000,0000,0000,,Quelltexte, man hatte den Objektcode, man\Nkonnte ihn desassemblieren zurück in den Dialogue: 0,0:04:43.75,0:04:50.16,Default,,0000,0000,0000,,Quelltext, ändern und neu kompilieren \Nfertig. Die Optimierungen, die ich jetzt Dialogue: 0,0:04:50.16,0:04:54.63,Default,,0000,0000,0000,,vorführen werde, zerstören diesen\Ninteressanten Aspekt, weil da Maschinencode Dialogue: 0,0:04:54.63,0:04:57.20,Default,,0000,0000,0000,,heraus kommt und weil da\Nauch Teile weg optimiert werden. Dialogue: 0,0:04:57.20,0:05:00.34,Default,,0000,0000,0000,,Es gibt also nicht mehr so den eins zu eins\NZusammenhang zwischen dem was man Dialogue: 0,0:05:00.34,0:05:04.58,Default,,0000,0000,0000,,geschrieben hat und dem was hinterher\Ntatsächlich im Prozessor ausgeführt wird. Dialogue: 0,0:05:04.58,0:05:08.12,Default,,0000,0000,0000,,Anders herum jedoch, hatte Forth\Nlange auch mit dem Problem zu kämpfen, Dialogue: 0,0:05:08.12,0:05:13.09,Default,,0000,0000,0000,,dass es immer auch ein bisschen langsam galt.\NDas habe ich geändert. Und ich möchte Dialogue: 0,0:05:13.09,0:05:17.95,Default,,0000,0000,0000,,gerne heute vorstellen was für\NOptimierungen man im Chip selbst Dialogue: 0,0:05:17.95,0:05:22.94,Default,,0000,0000,0000,,durchführen kann, natürlich aus der\NCompilertheorie heraus sind das alles alte Dialogue: 0,0:05:22.94,0:05:28.32,Default,,0000,0000,0000,,Hüte. Aber die meisten Compiler brauchen\Nsehr viel Speicher, laufen auf einem PC wo Dialogue: 0,0:05:28.32,0:05:31.98,Default,,0000,0000,0000,,es ja fast unbegrenzt davon gibt. Ich\Nmöchte aber einmal herausfinden welche Dialogue: 0,0:05:31.98,0:05:35.84,Default,,0000,0000,0000,,Optimierungen man in den Arbeitsspeichern\Neines kleinen Microcontrollers Dialogue: 0,0:05:35.84,0:05:42.26,Default,,0000,0000,0000,,implementieren kann. Dazu gehören\NTail-Call, Konstantenfaltung, Inlining, Dialogue: 0,0:05:42.26,0:05:48.19,Default,,0000,0000,0000,,Opcodierung und die Registerallokation. In\Nwelcher Architektur diese jeweils Dialogue: 0,0:05:48.19,0:05:51.88,Default,,0000,0000,0000,,implementiert sind steht da mit bei.\NNun will ich die ganzen einzelnen Dialogue: 0,0:05:51.88,0:05:57.03,Default,,0000,0000,0000,,Optimierungen einmal vorstellen. Tail-Call\Nist relativ simpel. Wenn das letzte in Dialogue: 0,0:05:57.03,0:06:01.31,Default,,0000,0000,0000,,einer Routine ein Call ist und danach\Ndirekt ein Return kommt, dann kann man das Dialogue: 0,0:06:01.31,0:06:04.92,Default,,0000,0000,0000,,auch durch einen Sprungbefehl ersetzen.\Nman braucht dann nicht den Umweg über den Dialogue: 0,0:06:04.92,0:06:09.03,Default,,0000,0000,0000,,Stack zu nehmen. Das ist eigentlich so\Nweit klar, nichts besonderes. Dialogue: 0,0:06:09.03,0:06:14.50,Default,,0000,0000,0000,,Konstantenfaltung bedeutet: Manchmal\Nmöchte man als Mensch etwas so schreiben, Dialogue: 0,0:06:14.50,0:06:19.97,Default,,0000,0000,0000,,dass man ein paar Konstanten nimmt, die\Nmultipliziert, zusammen verodert; all das Dialogue: 0,0:06:19.97,0:06:23.32,Default,,0000,0000,0000,,immer mit zu kompilieren wäre ja\Neigentlich Zeitverschwendung. Es steht ja Dialogue: 0,0:06:23.32,0:06:28.53,Default,,0000,0000,0000,,schon während der Kompilierung fest, was\Ndas Ergebnis dieser Berechnung sein wird, Dialogue: 0,0:06:28.53,0:06:32.04,Default,,0000,0000,0000,,der Compiler kann also durchaus diese\NRechnung schon während dem kompilieren Dialogue: 0,0:06:32.04,0:06:36.08,Default,,0000,0000,0000,,durchführen, nur noch das Ergebnis\Neinkompilieren. Hier sieht man mal ein Dialogue: 0,0:06:36.08,0:06:40.88,Default,,0000,0000,0000,,kleines Beispiel, also Sechs auf dem Stack\Nlegen, Sieben auf den Stack legen, beide Dialogue: 0,0:06:40.88,0:06:44.91,Default,,0000,0000,0000,,Werte vertauschen, miteinander\Nmultiplizieren und das ganze dann Dialogue: 0,0:06:44.91,0:06:50.71,Default,,0000,0000,0000,,aufsummieren. Eigentlich stehen die ersten\NTeile schon fest, das reicht wenn man 42 Dialogue: 0,0:06:50.71,0:06:54.92,Default,,0000,0000,0000,,plus kompilieren würde. Das ist die\NKonstantenfaltung. Das ist jetzt ein Dialogue: 0,0:06:54.92,0:06:59.23,Default,,0000,0000,0000,,glasklarer Fall, wo man das direkt sieht,\Naber manchmal gibt es auch aus anderen Dialogue: 0,0:06:59.23,0:07:02.21,Default,,0000,0000,0000,,Optimierungen heraus noch die\NMöglichkeit, dass Konstantenfaltungen Dialogue: 0,0:07:02.21,0:07:08.93,Default,,0000,0000,0000,,möglich werden kann. Das ist dann nicht\Nmehr ganz so offensichtlich. Dazu, wie das Dialogue: 0,0:07:08.93,0:07:12.27,Default,,0000,0000,0000,,implementiert wird, möchte ich erst\Neinmal kurz zeigen wie der klassische Dialogue: 0,0:07:12.27,0:07:17.50,Default,,0000,0000,0000,,Forth Compiler implementiert worden ist.\NEs war so, dass der Eingabestrom den der Dialogue: 0,0:07:17.50,0:07:22.79,Default,,0000,0000,0000,,Benutzer eingetippt hat in einzelne\NWörter, in Tokens zerhackt worden ist, Dialogue: 0,0:07:22.79,0:07:27.02,Default,,0000,0000,0000,,dann wurde geprüft ob es in der Liste der\Nbekannten Definitionen auftaucht, oder Dialogue: 0,0:07:27.02,0:07:31.58,Default,,0000,0000,0000,,eben auch nicht. Ist das der Fall, ist die\NFrage ob kompiliert werden soll oder Dialogue: 0,0:07:31.58,0:07:35.04,Default,,0000,0000,0000,,nicht. Es gibt einen Ausführ- und\Neinen Kompiliermodus, der eine interaktive Dialogue: 0,0:07:35.05,0:07:40.45,Default,,0000,0000,0000,,Sprache. Im Kompiliermodus und was nicht\Nimmer geht das – auch eine Spezialität Dialogue: 0,0:07:40.45,0:07:44.93,Default,,0000,0000,0000,,von Forth. Dann wird ein Aufruf in der\NDefinition einkompiliert, also ein Call Dialogue: 0,0:07:44.93,0:07:49.26,Default,,0000,0000,0000,,Befehl geschrieben. Immediate bedeutet\Nübrigens, dass etwas das kompiliert Dialogue: 0,0:07:49.26,0:07:53.75,Default,,0000,0000,0000,,werden soll selbst ausgeführt wird. Das\Nbraucht man für Kontrollstrukturen, die Dialogue: 0,0:07:53.75,0:07:58.48,Default,,0000,0000,0000,,dann noch so Sprünge handhaben müssen\Nund ähnliches und ansonsten ist man im Dialogue: 0,0:07:58.48,0:08:02.60,Default,,0000,0000,0000,,Ausführmodus, wird die Definition\Nausgeführt. Nichts gefunden: Versucht man Dialogue: 0,0:08:02.60,0:08:07.02,Default,,0000,0000,0000,,es als Zahl zu interpretieren und je\Nnachdem ob kompiliert werden soll oder Dialogue: 0,0:08:07.02,0:08:11.51,Default,,0000,0000,0000,,nicht, wird auf den Stack gelegt oder es\Nwird etwas kompiliert, was die Zahl dann Dialogue: 0,0:08:11.51,0:08:15.29,Default,,0000,0000,0000,,bei der Ausführung auf den Stack legen\Nwird. Wenn es auch keine gültige Zahl Dialogue: 0,0:08:15.29,0:08:21.38,Default,,0000,0000,0000,,ist, ist es ein Fehler. Um dort\NKonstantenfaltung einzfügen sind keine so Dialogue: 0,0:08:21.38,0:08:25.32,Default,,0000,0000,0000,,großen Änderungen nötig. Wichtig ist\Njetzt eigentlich nur, dass man die Dialogue: 0,0:08:25.32,0:08:30.42,Default,,0000,0000,0000,,Konstanten nicht kompiliert, zumindest\Nnicht gleich, sondern erst einmal sammelt Dialogue: 0,0:08:30.42,0:08:35.00,Default,,0000,0000,0000,,und dann wenn eine Operation kommt die bei\Nkonstanten Eingaben auch konstante Dialogue: 0,0:08:35.00,0:08:41.22,Default,,0000,0000,0000,,Ausgaben produziert, diese dann\Nauszuführen. Die Änderungen sind so, Dialogue: 0,0:08:41.22,0:08:46.62,Default,,0000,0000,0000,,dass jetzt ganz am Anfang der aktuelle\NStackfüllstand gemerkt werden muss, denn Dialogue: 0,0:08:46.62,0:08:50.75,Default,,0000,0000,0000,,man muss ja auch wissen, wie viele\NKonstanten gerade zur Verfügung stehen. Dialogue: 0,0:08:50.75,0:08:54.64,Default,,0000,0000,0000,,Soll es ausgeführt werden, wurde es\Ngefunden, dann brauchen wir keine Dialogue: 0,0:08:54.64,0:08:58.33,Default,,0000,0000,0000,,Konstantenfaltung machen, dann schmeißen\Nwir den Pointer wieder weg, alles gut, Dialogue: 0,0:08:58.33,0:09:03.99,Default,,0000,0000,0000,,vergessen wir. Sind wir im Kompiliermodus,\Nwird geprüft ob diese Definition mit Dialogue: 0,0:09:03.99,0:09:08.54,Default,,0000,0000,0000,,konstanten Eingaben auch eine konstante\NAusgabe produzieren kann und wenn ja, sind Dialogue: 0,0:09:08.54,0:09:13.74,Default,,0000,0000,0000,,genug dafür vorhanden. Eine Invertierung\Neiner Zahl braucht eine Konstante. Eine Dialogue: 0,0:09:13.74,0:09:18.90,Default,,0000,0000,0000,,Addition braucht zwei Konstanten usw. das\Nmuss geprüft werden. Wenn das gut geht Dialogue: 0,0:09:18.90,0:09:22.96,Default,,0000,0000,0000,,kann sie ausgeführt werden. Sie lässt\Ndann die Ergebnisse dort liegen und Dialogue: 0,0:09:22.96,0:09:26.28,Default,,0000,0000,0000,,dadurch, dass wir wusten wo der\NStackpointer vorher gewesen ist, wissen Dialogue: 0,0:09:26.28,0:09:30.65,Default,,0000,0000,0000,,wir auch wie viele Konstanten danach noch\Nauf dem Stack liegen geblieben sind. Es Dialogue: 0,0:09:30.65,0:09:37.61,Default,,0000,0000,0000,,kann also durchaus variabel viele\NAusgabekonstanten produzieren. Ist diese Dialogue: 0,0:09:37.61,0:09:42.75,Default,,0000,0000,0000,,Definition jedoch nicht faltbar, dann\Nbleibt uns nichts anderes übrig, als Dialogue: 0,0:09:42.75,0:09:46.47,Default,,0000,0000,0000,,alles was dort an Konstanten liegt\Neinzukompilieren und dann einen Dialogue: 0,0:09:46.47,0:09:51.82,Default,,0000,0000,0000,,klassischen Call Befehl zu machen. Ja,\Naber man kann den klassischen Callbefehl Dialogue: 0,0:09:51.82,0:09:54.76,Default,,0000,0000,0000,,auch nochmal ein bisschen abwandeln. Man\Nkann kucken ob da eine sehr kurze Dialogue: 0,0:09:54.76,0:09:59.48,Default,,0000,0000,0000,,Definition ist und dann Opcodes direkt\Neinfügen und bei Forth natürlich Dialogue: 0,0:09:59.48,0:10:04.03,Default,,0000,0000,0000,,Imediate überprüfen was bedeutet, dass\Ndiese Definition selber irgendwelche Dialogue: 0,0:10:04.03,0:10:11.32,Default,,0000,0000,0000,,Spezialfälle umsetzen kann. Nicht\Ngefunden, Zahlen bleiben stets auf dem Dialogue: 0,0:10:11.32,0:10:17.27,Default,,0000,0000,0000,,Stack liegen, damit sie halt später in\Ndie Konstantenfaltung rein kommen können. Dialogue: 0,0:10:17.27,0:10:21.00,Default,,0000,0000,0000,,Wichtig dabei ist zu wissen, dass dabei,\Nwährend die Zahlen gesammelt werden, ja Dialogue: 0,0:10:21.00,0:10:26.38,Default,,0000,0000,0000,,schon ein Merker in den Stack gesetzt\Nwurde um den Füllstand zu bestimmen. Ist Dialogue: 0,0:10:26.38,0:10:31.11,Default,,0000,0000,0000,,es nicht als Zahl zu interpretieren, ist\Nes ein Fehler. Das ist im Prinzip der Dialogue: 0,0:10:31.11,0:10:34.96,Default,,0000,0000,0000,,Kerngedanke um Konstantenfaltung in Forth\Nzu implementieren. Das hier ist Dialogue: 0,0:10:34.96,0:10:40.58,Default,,0000,0000,0000,,grundsätzlich auf jeder Architektur\Nmöglich wo Forth läuft und ist auch Dialogue: 0,0:10:40.58,0:10:45.71,Default,,0000,0000,0000,,relativ unabhängig davon wie das Forth\Ninnen drin implementiert hat. Ich habe Dialogue: 0,0:10:45.71,0:10:50.60,Default,,0000,0000,0000,,schon gesehen, dass jemand Matthias Troote\N(?) von der MForth für AVR, angefangen hat Dialogue: 0,0:10:50.60,0:10:54.12,Default,,0000,0000,0000,,das auch einzubauen und das noch\Nzusammen recognizern. Also es geht recht Dialogue: 0,0:10:54.12,0:11:00.12,Default,,0000,0000,0000,,gut, es ist auch Standardkonform. Die\Nnächste Sache: Inlining. Klar macht der Dialogue: 0,0:11:00.12,0:11:05.40,Default,,0000,0000,0000,,C-Kompiler auch. Kurze Definitionen die\Nnur ein paar Opcodes haben, können mit Dialogue: 0,0:11:05.40,0:11:09.64,Default,,0000,0000,0000,,einigen Vorsichtsmaßregeln auch direkt\Neingefügt werden, denn wozu sollte man Dialogue: 0,0:11:09.64,0:11:14.81,Default,,0000,0000,0000,,einen Call wohin tun, wenn die Opcodes\Nkürzer sind als der Call selbst. Und hier Dialogue: 0,0:11:14.81,0:11:18.58,Default,,0000,0000,0000,,das Beispiel von Plus. Man ruft nicht\Ndie primitive vom Plus auf wenn man den Dialogue: 0,0:11:18.58,0:11:24.94,Default,,0000,0000,0000,,Plus-Opcode direkt einfügen kann. Das\Nleuchtet eigentlich auch ein. Dialogue: 0,0:11:24.94,0:11:28.43,Default,,0000,0000,0000,,Opcodierungen - ich nenne es mal so, ich\Nweiß nicht wie es sonst genannt werden Dialogue: 0,0:11:28.43,0:11:34.55,Default,,0000,0000,0000,,soll – ist, wenn ein Opcode eine Konstante\Ndirekt in sich aufnehmen kann. Dann ist es Dialogue: 0,0:11:34.55,0:11:39.00,Default,,0000,0000,0000,,doch sinnvoller die Konstante direkt mit\Nzu opcodieren, als sie über den Stack zu Dialogue: 0,0:11:39.00,0:11:42.76,Default,,0000,0000,0000,,legen und dann darüber zu verwenden. Man\Nspart halt ein paar Takte und ein bisschen Dialogue: 0,0:11:42.76,0:11:48.97,Default,,0000,0000,0000,,Platz. Das hängt davon ab was für einen\NProzessor man hat. Beim MSP430 geht das Dialogue: 0,0:11:48.97,0:11:53.47,Default,,0000,0000,0000,,immer wunderbar, bei einem Cortex\Nmanchmal, der hat nur einige Opcodes die Dialogue: 0,0:11:53.47,0:11:58.80,Default,,0000,0000,0000,,Konstanten können und wenn man einen\NStackprozessor hat, geht das gar nicht. Dialogue: 0,0:11:58.80,0:12:03.03,Default,,0000,0000,0000,,Und der Regsiterallokator schließlich,\Nist die Überlegung, dass man Dialogue: 0,0:12:03.03,0:12:07.27,Default,,0000,0000,0000,,Zwischenergebnisse, die bei Forth\Ntraditionell auf dem Stack liegen würden, Dialogue: 0,0:12:07.27,0:12:11.22,Default,,0000,0000,0000,,versucht auf Register abzubilden. Denn\Nklar in der Stacksprache ist das ganz Dialogue: 0,0:12:11.22,0:12:15.76,Default,,0000,0000,0000,,etwas anderes als einen Prozessor der\Nhauptsächlich mit Registern arbeitet. Dialogue: 0,0:12:15.76,0:12:19.33,Default,,0000,0000,0000,,Beim ARM Cortex ist das ganz besonders\Nschlimm, denn er kann nicht direkt in den Dialogue: 0,0:12:19.33,0:12:23.53,Default,,0000,0000,0000,,Speicher zugreifen um da irgend etwas zu\Nberechnen, sondern er muss auf jeden Fall Dialogue: 0,0:12:23.53,0:12:28.26,Default,,0000,0000,0000,,immer aus dem Speicher in Register holen,\Nim Register etwas machen und in den Dialogue: 0,0:12:28.26,0:12:32.76,Default,,0000,0000,0000,,Speicher zurück schreiben. Das ist\Nziemlich aufwendig. Wenn man das abkürzen Dialogue: 0,0:12:32.76,0:12:36.24,Default,,0000,0000,0000,,kann, die Zwischenergebnisse gleich im\NRegister hält, kann man viel kürzere Dialogue: 0,0:12:36.24,0:12:40.55,Default,,0000,0000,0000,,Befehlssequenzen nutzen, die direkt\Nzwischen den Registern arbeiten. Dialogue: 0,0:12:40.55,0:12:44.66,Default,,0000,0000,0000,,Wichtig dabei ist noch, dass das ganze\Ntranspartent wird für den Programmierer, Dialogue: 0,0:12:44.66,0:12:48.74,Default,,0000,0000,0000,,wenn man also etwas macht, wo die logische\NStruktur des Stacks sichtbar wird oder Dialogue: 0,0:12:48.74,0:12:53.33,Default,,0000,0000,0000,,sichtbar werden könnte, muss der Compiler\Nauf jeden Fall zurück fallen und alles in Dialogue: 0,0:12:53.33,0:12:57.06,Default,,0000,0000,0000,,den richtigen Stack rein schreiben, so\Ndass man dann auch direkt im Stack Dialogue: 0,0:12:57.06,0:13:01.12,Default,,0000,0000,0000,,Manipulation machen kann, wenn das denn\Nmal notwendig ist und das ist bei Forth Dialogue: 0,0:13:01.12,0:13:06.15,Default,,0000,0000,0000,,ziemlich häufig, weil Forth Programmierer\Ngerne alle möglichen Tricks anwenden. Dialogue: 0,0:13:10.47,0:13:15.80,Default,,0000,0000,0000,,Das wesentliche für den Registerallokator\Nist, zu wissen wo welches Element gerade Dialogue: 0,0:13:15.80,0:13:20.00,Default,,0000,0000,0000,,ist, man muss also während der\NKompilierung ein Stackmodell mit laufen Dialogue: 0,0:13:20.00,0:13:24.93,Default,,0000,0000,0000,,lassen, worin vermerkt ist, wo diese Stack-\Nelemente eigentlich gerade sind. Sind sie Dialogue: 0,0:13:24.93,0:13:29.49,Default,,0000,0000,0000,,noch auf dem Stack selbst, also im\NArbeitsspeicher? Sind sie gerade in einem Dialogue: 0,0:13:29.49,0:13:35.01,Default,,0000,0000,0000,,Register drin? Wenn ja, in welchem? Oder,\Nwenn neue Zwischenergebnisse auftreten: Dialogue: 0,0:13:35.01,0:13:38.75,Default,,0000,0000,0000,,Haben wir noch genug Register? Denn wenn\Nmehr Zwischenergebnisse da sind als Dialogue: 0,0:13:38.75,0:13:41.93,Default,,0000,0000,0000,,Register zur Verfügung stehen, dann\Nmüssen die Register wieder in den Dialogue: 0,0:13:41.93,0:13:46.93,Default,,0000,0000,0000,,Arbeitsspeicher auf den Stack geschrieben\Nwerden und das ist es was innen drin das Dialogue: 0,0:13:46.93,0:13:54.50,Default,,0000,0000,0000,,besondere ausmacht. Man kann es sehr klein\Nimplementieren, aber man muss daran Dialogue: 0,0:13:54.50,0:13:58.52,Default,,0000,0000,0000,,denken, dass das sehr seltsam ist,\Ndass das im Microcontroller läuft, Dialogue: 0,0:13:58.52,0:14:03.01,Default,,0000,0000,0000,,normalerweise gibt es bei Register-\Nallokatoren viele Algorithmen drum herum, Dialogue: 0,0:14:03.01,0:14:06.24,Default,,0000,0000,0000,,die überlegen, wie man das\Nmöglichst gut über möglichst weite Dialogue: 0,0:14:06.24,0:14:10.56,Default,,0000,0000,0000,,Strecken im Programm machen kann. Ich habe\Nes sehr einfach gemacht. An den Stellen wo Dialogue: 0,0:14:10.56,0:14:15.25,Default,,0000,0000,0000,,Kontrollstrukturen verzweigen hört man\Neinfach auf. Man schreibt dann alles in Dialogue: 0,0:14:15.25,0:14:19.37,Default,,0000,0000,0000,,den Stack und fertig. Ist eine sehr simple\NImplementation und globale Optimierung Dialogue: 0,0:14:19.37,0:14:24.98,Default,,0000,0000,0000,,habe ich gar nicht drin. Aber es ist ein\NAnfang. Das sind jetzt all die Dialogue: 0,0:14:24.98,0:14:29.95,Default,,0000,0000,0000,,Optimierungen die angesprochen werden\Nsollen. Nun will ich ein paar Beispiele Dialogue: 0,0:14:29.95,0:14:34.42,Default,,0000,0000,0000,,dafür zeigen. Erst einmal muss ich aber\Nnoch sagen: Mercrisp-Ice ist nicht allein Dialogue: 0,0:14:34.42,0:14:38.92,Default,,0000,0000,0000,,meine Arbeit sondern basiert auf vielen\Nvielen anderen schönen Sachen die auch Dialogue: 0,0:14:38.92,0:14:43.72,Default,,0000,0000,0000,,vorgestellt worden sind. James Bowman hat\Nden J1 Prozessor entwickelt. Clifford Dialogue: 0,0:14:43.72,0:14:48.51,Default,,0000,0000,0000,,Wolf, Cotton Seed und Mathias Lasser haben\Ndie erste freie Toolchain für FPGAs Dialogue: 0,0:14:48.51,0:14:55.57,Default,,0000,0000,0000,,entwickelt und darauf basiert das alles.\NDa drin habe ich die Konstantenfaltung, Dialogue: 0,0:14:55.57,0:15:00.93,Default,,0000,0000,0000,,automatisches Inline kurzer Definitionen \Nund Tail-Call-Optimierung. Hier ist jetzt Dialogue: 0,0:15:00.93,0:15:05.22,Default,,0000,0000,0000,,mal ein kleines Beispiel. Das ist noch\Naus der LEDcom Implementation, wie man Dialogue: 0,0:15:05.22,0:15:08.75,Default,,0000,0000,0000,,über eine Leuchtdiode kommunizieren kann.\NFür die die jetzt nicht bei der Assembly Dialogue: 0,0:15:08.75,0:15:13.40,Default,,0000,0000,0000,,gesehen haben, es ist so, dass man eine\NLeuchtdiode nicht nur zum Leuchten sondern Dialogue: 0,0:15:13.40,0:15:17.19,Default,,0000,0000,0000,,auch als Fotodiode nutzen kann und wenn\Nman das schnell hintereinander abwechselt Dialogue: 0,0:15:17.19,0:15:20.30,Default,,0000,0000,0000,,leuchtet und kucken wie hell es ist, hat\Nman eine serielle Schnittstelle über eine Dialogue: 0,0:15:20.30,0:15:24.21,Default,,0000,0000,0000,,Leuchtdiode. Was natürlich auch dazu\Nführt, wenn man den Compiler auch noch im Dialogue: 0,0:15:24.21,0:15:27.18,Default,,0000,0000,0000,,Chip hat, dann kann man über die Power On\NLampe seiner Kaffeemaschine neue Dialogue: 0,0:15:27.18,0:15:30.46,Default,,0000,0000,0000,,Brühprogramme einspeichern und\NFehlermeldungen auslesen. Aber das ist Dialogue: 0,0:15:30.46,0:15:32.48,Default,,0000,0000,0000,,jetzt noch etwas anderes,\Ndas nur so nebenbei. Dialogue: 0,0:15:32.48,0:15:35.59,Default,,0000,0000,0000,,{\i1}Gelächter{\i0}\NKucken wir uns das jetzt einmal genauer an. Dialogue: 0,0:15:35.59,0:15:39.47,Default,,0000,0000,0000,,Als erstes werden Konstanten definiert\Nfür Anode und Kathode, wo die gerade Dialogue: 0,0:15:39.47,0:15:44.81,Default,,0000,0000,0000,,angeschlossen sind und dann eine\NDefinition, – "shine" soll sie heißen – Dialogue: 0,0:15:44.81,0:15:48.34,Default,,0000,0000,0000,,wo die Anode und die Kathode beide als\NAusgang gesetzt werden und die Anode Dialogue: 0,0:15:48.34,0:15:53.27,Default,,0000,0000,0000,,"high". Wenn man sich das jetzt einmal\Ndisassembliert ansieht ist da schon Dialogue: 0,0:15:53.27,0:15:59.69,Default,,0000,0000,0000,,einiges passiert. Als erstes "Anode,\NKathode or". Ist zu einer einzigen Konstante Dialogue: 0,0:15:59.69,0:16:05.51,Default,,0000,0000,0000,,Hex F zusammen gefasst worden. Das\Nwar die Konstantenfaltung. Dann als Dialogue: 0,0:16:05.51,0:16:13.27,Default,,0000,0000,0000,,nächstes, ganz unten, das letzte wäre\Nein Call um etwas zu speichern im io-Teil. Dialogue: 0,0:16:13.27,0:16:16.78,Default,,0000,0000,0000,,Dort wird jetzt ein Jump und kein Call\Neingefügt, das war die Dialogue: 0,0:16:16.78,0:16:21.43,Default,,0000,0000,0000,,Tail-Call-Optimierung. Ist das\Nsoweit noch ganz klar? Dialogue: 0,0:16:25.10,0:16:28.84,Default,,0000,0000,0000,,Hier kann man noch einmal das Inlining sehen, Dialogue: 0,0:16:28.84,0:16:32.48,Default,,0000,0000,0000,,denn an der Stelle hier,\NKathode AND, das "AND" wurde auch direkt Dialogue: 0,0:16:32.48,0:16:37.61,Default,,0000,0000,0000,,eingefügt als Alu-Opcode und wurde nicht\Nals Call eingefügt und dann darum herum Dialogue: 0,0:16:37.61,0:16:41.68,Default,,0000,0000,0000,,natürlich wieder die üblichen\NVerdächtigen. Unten passiert Tail-Call Dialogue: 0,0:16:41.68,0:16:45.13,Default,,0000,0000,0000,,und für die Konstantenfaltung habe ich\Nnochmal ein kleines Beispiel und zwar das Dialogue: 0,0:16:45.13,0:16:50.11,Default,,0000,0000,0000,,was ich ganz am Anfang hatte, wie das\Naussieht. Ganz einfach: Es wird Dialogue: 0,0:16:50.11,0:16:53.85,Default,,0000,0000,0000,,ausgerechnet vom Compiler schon während\Ndes kompilierens, die Konstante wird Dialogue: 0,0:16:53.85,0:16:58.00,Default,,0000,0000,0000,,geschrieben. Der Stack-Prozessor kann\Nkeine Konstante in Opcodes mit einbauen, Dialogue: 0,0:16:58.00,0:17:03.44,Default,,0000,0000,0000,,also gibt es da keine weitere Optimierung\Nmehr. Dann kommt plus. Plus ist drin im Dialogue: 0,0:17:03.44,0:17:07.63,Default,,0000,0000,0000,,Prozessor und der J1 hat noch die\NMöglichkeit auch gleich den Rücksprung Dialogue: 0,0:17:07.63,0:17:14.76,Default,,0000,0000,0000,,mit im Opcode zu haben. Fertig. Tail-Call\Nim Prinzip auch erledigt. So. Zum J1 Dialogue: 0,0:17:14.76,0:17:18.79,Default,,0000,0000,0000,,Prozessor kann man viel erzählen, ich\Nwill nur kurz sagen, er ist sehr klein, Dialogue: 0,0:17:18.79,0:17:22.53,Default,,0000,0000,0000,,sehr verständlich - das sind 200 Zeilen\NVerilog, es lohnt sich wirklich sich das Dialogue: 0,0:17:22.53,0:17:29.59,Default,,0000,0000,0000,,mal anzukucken. Schaut mal rein, wenn\Nihr euch dafür interessiert. MSP430, das Dialogue: 0,0:17:29.59,0:17:32.19,Default,,0000,0000,0000,,ist ein Prozessor, der sehr viele\Nverschiedene Adressierungsarten Dialogue: 0,0:17:32.19,0:17:36.87,Default,,0000,0000,0000,,unterstützt und auch eigentlich recht gut\Nzu Forth passt. Mit Tail-Call gab es so Dialogue: 0,0:17:36.87,0:17:40.27,Default,,0000,0000,0000,,ein paar Probleme, weil es einige Tricks\Ngibt, die mit den Rücksprungadressen Dialogue: 0,0:17:40.27,0:17:44.49,Default,,0000,0000,0000,,etwas machen und dann knackst es. Also\Nhabe ich keinen Tail-Call drin. Aber Dialogue: 0,0:17:44.49,0:17:49.54,Default,,0000,0000,0000,,Konstantenfaltung, Inlining und\NOpcodierung sind drin. Hier noch ein paar Dialogue: 0,0:17:49.54,0:17:55.30,Default,,0000,0000,0000,,Beispiele. Hier kann man wieder sehen, es\Nwerden Konstanten definiert und ganz am Dialogue: 0,0:17:55.30,0:17:59.22,Default,,0000,0000,0000,,Ende sollen dann wieder Leuchtdioden\Nangesteuert werden, soll der Taster Dialogue: 0,0:17:59.22,0:18:04.56,Default,,0000,0000,0000,,vorbereitet werden, hat man nur\NInitialisierung für so ein Launchpad. Dialogue: 0,0:18:04.56,0:18:09.82,Default,,0000,0000,0000,,Das sieht kompiliert so aus. Es tritt mehreres\Nin Aktion. Die Konstanten kommen wieder Dialogue: 0,0:18:09.82,0:18:15.87,Default,,0000,0000,0000,,über die Konstantenfaltung und diese\NBefehle werden über Inlining eingebaut Dialogue: 0,0:18:15.87,0:18:20.30,Default,,0000,0000,0000,,und dadurch, dass sie direkt Parameter in\Nden Opcode übernehmen können, kriegen Dialogue: 0,0:18:20.30,0:18:24.30,Default,,0000,0000,0000,,sie auch die Opcodierungen, so, dass das\Nwas hinterher heraus kommt eigentlich das Dialogue: 0,0:18:24.30,0:18:28.45,Default,,0000,0000,0000,,gleiche ist was ich auch in Assembler\Nschreiben würde. Man sieht es auch immer, Dialogue: 0,0:18:28.45,0:18:33.26,Default,,0000,0000,0000,,die Zahlen immer nur ein Opcode, das\Nwar es. Das letzte ist übrigens der Dialogue: 0,0:18:33.26,0:18:38.53,Default,,0000,0000,0000,,Rücksprung, der sieht immer bisschen\Nkomisch aus, aber das funktioniert. Dialogue: 0,0:18:38.53,0:18:43.74,Default,,0000,0000,0000,,Mecrisp-Stellaris ist eine direkte\NPortierung von Mecrisp auf einen ARM Dialogue: 0,0:18:43.74,0:18:48.50,Default,,0000,0000,0000,,Cortex M4 gewesen. Stellaris-Launchpad war\Ndie erste Plattform die unterstützt war. Dialogue: 0,0:18:48.50,0:18:53.59,Default,,0000,0000,0000,,Der Name klingt gut, habe ich so gelassen.\NEigentlich identisch mit dem MSP430, wenn Dialogue: 0,0:18:53.59,0:18:57.65,Default,,0000,0000,0000,,es um Optimierung geht. Aber ich habe\Njetzt gerade noch (?) müssen noch / Dialogue: 0,0:18:57.65,0:19:00.87,Default,,0000,0000,0000,,werden noch fertig geworden, einen\NRegisterallokator rein bekommen, den Dialogue: 0,0:19:00.87,0:19:04.74,Default,,0000,0000,0000,,möchte ich noch kurz zeigen. Hier sieht\Nman ein Beispiel was schon ein bisschen Dialogue: 0,0:19:04.74,0:19:09.14,Default,,0000,0000,0000,,schwieriger ist. Das oben ist der gray\NCode, der gray Code ist so eine Sache, Dialogue: 0,0:19:09.14,0:19:13.50,Default,,0000,0000,0000,,wenn man darin zählt, ändert sich immer\Nnur eine Bitstelle. Na gut, aber darum Dialogue: 0,0:19:13.50,0:19:17.55,Default,,0000,0000,0000,,soll es jetzt nicht gehen, sondern darum,\Ndass man hier sieht, das keine Dialogue: 0,0:19:17.55,0:19:24.23,Default,,0000,0000,0000,,Stackbewegungen mehr da sind. Das oberste\NStackelement ist im ARM in Register 6 enthalten Dialogue: 0,0:19:24.23,0:19:28.23,Default,,0000,0000,0000,,und die Zwischenergebnisse, also duplicate\Nlegt das oberste Element nochmal auf den Dialogue: 0,0:19:28.23,0:19:34.02,Default,,0000,0000,0000,,Stack, dann kommt die Eins; man sieht\Nschon, der Schiebebefehl hat als Dialogue: 0,0:19:34.02,0:19:38.57,Default,,0000,0000,0000,,Zielregister ein anderes Register, also\Nein reines Zwischenergebnisregister und Dialogue: 0,0:19:38.57,0:19:42.37,Default,,0000,0000,0000,,exklusiv-oder nimmt es von da und tut es\Nwieder auf das oberste Stackelement, Dialogue: 0,0:19:42.37,0:19:48.28,Default,,0000,0000,0000,,so dass man gar kein Stackbewegung mehr\Nbraucht und das Quadrat genauso. Das ist Dialogue: 0,0:19:48.28,0:19:52.21,Default,,0000,0000,0000,,eben die Sache, dass man versucht\NZwischenergebnisse in Registern zu halten, Dialogue: 0,0:19:52.21,0:19:58.53,Default,,0000,0000,0000,,soweit möglich. Das hier ist ein klein\Nbisschen aufwendigeres Beispiel. Hier ist Dialogue: 0,0:19:58.53,0:20:02.54,Default,,0000,0000,0000,,es so, das Variablen geholt werden sollen,\Nzwei Stück, addiert und wieder zurück Dialogue: 0,0:20:02.54,0:20:07.07,Default,,0000,0000,0000,,geschrieben. Im ARM Cortex kann man\Nübrigens einen Offset an jeden Ladebefehl Dialogue: 0,0:20:07.07,0:20:12.07,Default,,0000,0000,0000,,daran fügen. Am Anfang wird also die\NAdresse der Variablen geladen, dann wird Dialogue: 0,0:20:12.07,0:20:15.73,Default,,0000,0000,0000,,die erste Variable geholt, dann die\Nzweite, beide werden addiert und zurück Dialogue: 0,0:20:15.73,0:20:18.91,Default,,0000,0000,0000,,geschrieben. Wieder keine\NStackbewegungen nötig. Dialogue: 0,0:20:22.02,0:20:27.04,Default,,0000,0000,0000,,Wer jetzt ein bisschen neugierig geworden\Nist und sofort loslegen möchte: Dialogue: 0,0:20:27.04,0:20:29.44,Default,,0000,0000,0000,,Alle Launchpads von Texas Instruments Dialogue: 0,0:20:29.44,0:20:34.75,Default,,0000,0000,0000,,werden unterstützt, die ARM Cortex, viele\Ndavon, von STM, Texas Instruments, Dialogue: 0,0:20:34.75,0:20:42.05,Default,,0000,0000,0000,,Infineon neuerdings und Freescale und wer\Nandere Systeme benutzt, kann natürlich Dialogue: 0,0:20:42.05,0:20:47.26,Default,,0000,0000,0000,,auch gerne Forth ausprobieren. Es gibt\NGforth für den PC, AmForth für die Atmel Dialogue: 0,0:20:47.26,0:20:55.05,Default,,0000,0000,0000,,AVR-Reihe, für PIC gibt es FlashForth und\Nfür den Z80 und einige andere CamelForth. Dialogue: 0,0:20:55.05,0:20:59.79,Default,,0000,0000,0000,,Ganz ganz viele verschiedene. Es kommt\Nnämlich daher, das dadurch, dass Forth Dialogue: 0,0:20:59.79,0:21:02.48,Default,,0000,0000,0000,,recht klein ist und recht leicht\Nimplementiert werden kann, dass viele Dialogue: 0,0:21:02.48,0:21:06.61,Default,,0000,0000,0000,,Leute zum kennen lernen der Sprache\Neinfach selber ihren eigenen Compiler Dialogue: 0,0:21:06.61,0:21:10.90,Default,,0000,0000,0000,,implementieren. Das macht Spaß und ich\Ndenke – auch wenn man mir jetzt dafür den Dialogue: 0,0:21:10.90,0:21:15.90,Default,,0000,0000,0000,,Kopf abreißen wird, in einigen Kreisen –\Nman möge es tun. Denn dabei lernt man Dialogue: 0,0:21:15.90,0:21:19.67,Default,,0000,0000,0000,,sehr viel über das Innere kennen. Andere\Nsagen natürlich man soll sich erst einmal Dialogue: 0,0:21:19.67,0:21:22.79,Default,,0000,0000,0000,,mit der Philosophie der Sprache\Nauseinander setzen. Sei es drum, beide Dialogue: 0,0:21:22.79,0:21:25.92,Default,,0000,0000,0000,,Seiten haben ihre guten Argumente. Ich\Nmuss sage, ich habe direkt mit dem Dialogue: 0,0:21:25.92,0:21:30.63,Default,,0000,0000,0000,,Schreiben meines ersten Compilers begonnen\Nund stehe nun ja. Ich habe noch einige Dialogue: 0,0:21:30.63,0:21:35.31,Default,,0000,0000,0000,,Beispiele mitgebracht und ich habe\Nnoch ein bisschen Zeit über. Das hier Dialogue: 0,0:21:35.31,0:21:40.26,Default,,0000,0000,0000,,generiert Zufallszahlen mit dem Rauschen\Ndes AD-Wandler der einen Temperatursensor Dialogue: 0,0:21:40.26,0:21:44.69,Default,,0000,0000,0000,,trägt. Das ist einfach eine kleine\NSchleife, die 16 mal durchläuft und es Dialogue: 0,0:21:44.69,0:21:50.41,Default,,0000,0000,0000,,wird jeweils aus dem Analogkanal zehn im\NMSP430 ein Wert gelesen, das unterste Bit Dialogue: 0,0:21:50.41,0:21:58.61,Default,,0000,0000,0000,,wird maskiert, dann hinzu getan zu dem was\Nman schon hat und das nächste Bit. Das Dialogue: 0,0:21:58.61,0:22:03.58,Default,,0000,0000,0000,,ist das wie es kompiliert worden ist. Als\Nerstes werden die Schleifenregister frei Dialogue: 0,0:22:03.58,0:22:08.99,Default,,0000,0000,0000,,gemacht, dann wird eine Null auf den Stack\Ngelegt, wenn man es sich hier nochmal Dialogue: 0,0:22:08.99,0:22:13.72,Default,,0000,0000,0000,,ankuckt, eine Null ganz am Anfang wurde da\Nschon hingelegt, also der Wert wo dann Dialogue: 0,0:22:13.72,0:22:20.61,Default,,0000,0000,0000,,hinterher die Bits aus dem AD-Wandler rein\Nkommen. Dann, der Shiftbefehl wurde per Dialogue: 0,0:22:20.61,0:22:27.64,Default,,0000,0000,0000,,Inlining eingefügt, dann kommt die\NKonstante Zehn auf den Stack. Leider gibt Dialogue: 0,0:22:27.64,0:22:32.54,Default,,0000,0000,0000,,es nur einen Push-Befehl im MSP430, also\Nhier die Kombination aus Stackpointer Dialogue: 0,0:22:32.54,0:22:36.79,Default,,0000,0000,0000,,erniedrigen, etwas darauf legen, dann wird\Nanalog klassisch ausgeführt mit einem Dialogue: 0,0:22:36.79,0:22:41.90,Default,,0000,0000,0000,,Callbefehl und anschließend wieder\NInlining und Opcodierungen. Das Maskieren Dialogue: 0,0:22:41.90,0:22:46.25,Default,,0000,0000,0000,,des unteren Bits ist nur noch ein Opcode,\NXor genauso und kann direkt eingefügt Dialogue: 0,0:22:46.25,0:22:51.98,Default,,0000,0000,0000,,werden. Dann wird der Schleifenzähler\Nerhöht, verglichen und die Schleife Dialogue: 0,0:22:51.98,0:22:56.61,Default,,0000,0000,0000,,springt zurück. Wenn die Schleife fertig\Nist, Register zurück holen, Rücksprung. Dialogue: 0,0:22:56.61,0:23:00.43,Default,,0000,0000,0000,,Hier hat man mal die ganzen Optimierungen\Nalle in einem gesehen, wie das in einem Dialogue: 0,0:23:00.43,0:23:04.12,Default,,0000,0000,0000,,echten Beispiel aussieht, weil das davor\Nja doch so ein bisschen gestellt gewesen ist Dialogue: 0,0:23:04.12,0:23:09.09,Default,,0000,0000,0000,,um es schön zu zeigen. Das hier ist\Nein etwas größeres Beispiel auf Dialogue: 0,0:23:09.09,0:23:14.49,Default,,0000,0000,0000,,dem ARM Cortex. Die Bitexponentialfunktion\Nist so etwas wie eine Exponentialfunktion, Dialogue: 0,0:23:14.49,0:23:18.32,Default,,0000,0000,0000,,die aber auf Integer funktioniert. Und\Nhier kann man auch nochmal verschiedene Dialogue: 0,0:23:18.32,0:23:22.19,Default,,0000,0000,0000,,Sachen sehen wie das im ARM Cortex\Naussieht und was passiert wenn Dialogue: 0,0:23:22.19,0:23:29.57,Default,,0000,0000,0000,,Kontrollsturkturen dazwischen kommen. Ganz\Nam Anfang wird verglichen ob der Wert eine Dialogue: 0,0:23:29.57,0:23:34.50,Default,,0000,0000,0000,,bestimmte Größe erreicht hat. Dann,\Ndieses "push lr" kommt daher, dass im ARM Dialogue: 0,0:23:34.50,0:23:39.09,Default,,0000,0000,0000,,Cortex so ein Link-Register existiert,\Nder dafür da ist, dass Dialogue: 0,0:23:39.09,0:23:43.13,Default,,0000,0000,0000,,Unterprogrammeinsprünge die keine weitere\NEbene haben direkt im Register bleiben und Dialogue: 0,0:23:43.13,0:23:46.78,Default,,0000,0000,0000,,nicht auf den Return-Stack gelegt werden.\NWenn aber Kontrollstrukturen kommen und Dialogue: 0,0:23:46.78,0:23:50.57,Default,,0000,0000,0000,,noch nicht klar ist ob in einem der zwei\NZweige vielleicht doch noch ein Dialogue: 0,0:23:50.57,0:23:54.89,Default,,0000,0000,0000,,Unterpgrogramm aufgerufen werden muss,\Nmuss er jetzt gesichert werden. Dann zeigt Dialogue: 0,0:23:54.89,0:23:59.07,Default,,0000,0000,0000,,der Sprung der zum "if" gehört, eine Zahl\Nwird herunter geworfen und eine Neue rein Dialogue: 0,0:23:59.07,0:24:03.69,Default,,0000,0000,0000,,gelegt, was aber im Endeffekt nur ein\NLadebefehl ist, weil ja der Register Top Dialogue: 0,0:24:03.69,0:24:08.08,Default,,0000,0000,0000,,of Stack ohnehin schon die ganze Zeit\Nbereit gelegen hat. Im else Zweig ist ein Dialogue: 0,0:24:08.08,0:24:13.48,Default,,0000,0000,0000,,bisschen mehr zu tun. Das duplicate\Nbrauchen wir nicht. Ein Registerallokator Dialogue: 0,0:24:13.48,0:24:20.49,Default,,0000,0000,0000,,dahinter. Dann der Vergleich, wieder das\N"if", hier bei "1 rshift" kann man wieder Dialogue: 0,0:24:20.49,0:24:23.55,Default,,0000,0000,0000,,sehen, dass das alles in einen Opcode\Nzusammen gefügt worden ist, das ist Dialogue: 0,0:24:23.55,0:24:32.38,Default,,0000,0000,0000,,wieder Kombinationen aus Konstantenfaltung\Nund Inlining. Dann, der else-Zweig, so, Dialogue: 0,0:24:32.38,0:24:36.41,Default,,0000,0000,0000,,hier ist ein bisschen mehr zu tun. Man\Nkann jetzt auch sehen, dass mehrere Dialogue: 0,0:24:36.41,0:24:42.94,Default,,0000,0000,0000,,Zwischenergebnisse im Register auftreten.\NAlso r3 und r2, beide mit dabei, die Werte Dialogue: 0,0:24:42.94,0:24:46.22,Default,,0000,0000,0000,,werden jetzt nicht mehr auf den Stack\Ngelegt, sondern zwischen den Registern hin Dialogue: 0,0:24:46.22,0:24:50.44,Default,,0000,0000,0000,,und her geschoben. Vielleicht wird das\Njetzt ein bisschen unübersichtlich, aber Dialogue: 0,0:24:50.44,0:24:54.62,Default,,0000,0000,0000,,ich denke, wenn man das direkt vergleicht,\Nich habe immer dort wo Assembler steht Dialogue: 0,0:24:54.62,0:24:57.83,Default,,0000,0000,0000,,auch den Forth Quelltext daneben\Nund das sind die Opcodes die jeweils Dialogue: 0,0:24:57.83,0:25:04.20,Default,,0000,0000,0000,,für die Zeile generiert werden.\NWas man hier noch sehen kann, Dialogue: 0,0:25:04.20,0:25:08.95,Default,,0000,0000,0000,,dass man im ARM Cortex leider nicht\Neine Konstante in den einzelnen Befehl mit Dialogue: 0,0:25:08.95,0:25:14.85,Default,,0000,0000,0000,,einfügen kann. Deswegen wird es über ein\Nanderes Register geladen. Aber, andere Dialogue: 0,0:25:14.85,0:25:18.81,Default,,0000,0000,0000,,Sachen – wie der Shiftbefehl – können\NKonstanten direkt übernehmen. Das ist Dialogue: 0,0:25:18.81,0:25:24.77,Default,,0000,0000,0000,,hier passiert und ganz am Ende muss\Naufgeräumt werden. Bislang war das kein\N Dialogue: 0,0:25:24.77,0:25:29.69,Default,,0000,0000,0000,,Problem, weil das oberste Element immer in\Nr6 geblieben ist. Jetzt aber wurden durch Dialogue: 0,0:25:29.69,0:25:35.99,Default,,0000,0000,0000,,die Zwischenergebnisse und das hin und her\Njonglieren, der Fall erreicht, dass das Dialogue: 0,0:25:35.99,0:25:39.78,Default,,0000,0000,0000,,oberste Element auf dem Stack eben nicht\Nmehr in dem Register ist der normalerweise\N Dialogue: 0,0:25:39.78,0:25:44.63,Default,,0000,0000,0000,,das oberste Element trägt. Deswegen der\Nvorletzte Befehl, der move-Befehl dient Dialogue: 0,0:25:44.63,0:25:48.74,Default,,0000,0000,0000,,zum aufräumen. Der hat kein Äquivalent\Nin Forth, aber er dient dazu, das Dialogue: 0,0:25:48.74,0:25:52.91,Default,,0000,0000,0000,,Stackmodell was gerade in einem Zustand\Nist wie es sonst nicht sein sollte wieder Dialogue: 0,0:25:52.91,0:25:56.07,Default,,0000,0000,0000,,auf den kanonischen Stack zurück zu\Nführen, damit an der Schnittstelle alles Dialogue: 0,0:25:56.07,0:26:00.44,Default,,0000,0000,0000,,sauber übergeben werden kann. Wohl\Ngemerkt, globale Optimierungen gibt es Dialogue: 0,0:26:00.44,0:26:04.47,Default,,0000,0000,0000,,noch nicht, wird es wohl auch erst einmal\Nnicht geben, aber man kann schon einmal Dialogue: 0,0:26:04.47,0:26:08.52,Default,,0000,0000,0000,,sehen, dass man die gesamte Sache ohne\NStackbewegung geschafft hat, mal davon Dialogue: 0,0:26:08.52,0:26:12.22,Default,,0000,0000,0000,,abgesehen, das der Returnstack einmal die\NAdresse zum Rücksprung aufgenommen hat, Dialogue: 0,0:26:12.22,0:26:17.22,Default,,0000,0000,0000,,was ich aber nicht vermeiden konnte, weil\Ndieser Compiler nicht voraus schauen kann. Dialogue: 0,0:26:17.22,0:26:21.50,Default,,0000,0000,0000,,Er kann immer nur sehen, wo er gerade ist\Nund versuchen dafür zu generieren. Um das Dialogue: 0,0:26:21.50,0:26:24.81,Default,,0000,0000,0000,,weglassen zu können, müsste man dann\Nvorausschauen können um zu sehen was Dialogue: 0,0:26:24.81,0:26:30.17,Default,,0000,0000,0000,,in den Kontrollstrukturen\Nvielleicht doch noch passiert. Dialogue: 0,0:26:30.17,0:26:33.17,Default,,0000,0000,0000,,Damit bin ich am Ende\Nangelangt, alle Beispiele gezeigt. Kann Dialogue: 0,0:26:33.17,0:26:37.15,Default,,0000,0000,0000,,ich nur noch wünschen: Alles Gute zum\Nneuen Jahr! Wenn dann noch Fragen sind, Dialogue: 0,0:26:37.15,0:26:40.18,Default,,0000,0000,0000,,kommt gleich nochmal zu mir, schreibt mir,\Nich freue mich über viele E-Mails. Dialogue: 0,0:26:40.18,0:26:41.85,Default,,0000,0000,0000,,Vielen Dank. Dialogue: 0,0:26:41.85,0:26:43.16,Default,,0000,0000,0000,,{\i1}Applaus{\i0} Dialogue: 0,0:26:43.16,0:26:46.92,Default,,0000,0000,0000,,Herald: Okay, alles klar,\Nvielen Dank Matthias. Dialogue: 0,0:26:46.92,0:26:50.56,Default,,0000,0000,0000,,{\i1}Abspannmusik{\i0} Dialogue: 0,0:26:50.56,0:26:57.00,Default,,0000,0000,0000,,subtitles created by c3subtitles.de\NJoin, and help us!