 Dann ist mir jetzt eine ganz besondere Freude, Mathias Koch vorzustellen und der wird jetzt über Compiler-Optimierung für FORTH im Mikrocontroller sprechen. Bitte einen Warmer-Aplaus für Mathias. Guten Tag, hallo. Wie gesagt, Compiler-Optimierung für FORTH im Mikrocontroller und ganz zur Eröffnung habe ich mal eine Frage, wer von euch kennt FORTH eigentlich schon? Okay, so einfach die Hälfte. Das bedeutet aber, ich sollte besser noch einmal kurz erklären, was diese Sprache eigentlich ausmacht. Es ist eine Sprache, die auf den Modellanstegs basiert. Vielleicht könnt ihr die umgekehrte polnische Notation, wo so ist, dass die Parameter kommen und dann die Operatoren. Man legt also Wert auf den Stack, von oben kommt die Operatoren, neben das etwas Breschende, fast links wieder drauf. Es gibt auch einen zweiten Stack, den Return-Stack, worüber die Rückbrunkadressen gehandhabt werden. Das bedeutet, man kann nacheinander die verschiedenen Operatoren aufrufen und muss nicht wie bei CD-Stacks vorhin hin und her kopieren. Der Compiler selbst ist sehr simpel aufgebaut. Es passiert darauf, dass man den Eingabestrom, was der Mensch Tipps nimmt, in Wartezeit, also an Space, Tabulator, Teilenumbruch, wenn ein Wort gefunden wird, wird in der Liste der Bekanntwörter gesucht, entweder ausgeführt oder kompiliert. Und wenn es nicht gefunden werden kann, wird das Zahl interpretiert und auf den Stack gelegt. Oder es wird etwas kompiliert, um diese Zahl dann später auf den Stack zu legen. Das war nicht schon die Sprache. Das Besondere daran ist, dass sie klein genug ist, dass sie in eine Mikro-Kontrolle installiert werden kann. Das dazu führt, dass man dann mit einem Termine mit seinem Chip setzern kann und in den Herausaus probieren, ob der Hardware gut funktioniert, weil man dann nicht viele kleine Testprogramme schreiben muss, sondern ganz einfach von Hand an den Leitungen wackeln kann und alle Definitionen, die man geschrieben hat, auch sofort interaktiv ausprobieren kann. Das führt dann auch dazu, dass die Definition natürlich gleich in der Hardware läuft und auch gleich mit Echtzeit, so dass man nur die Fehler durch das Tag vereinfachen kann. Das ist so ein bisschen eine Einführung in Fahrt. Ich selbst habe diese Sprachen nicht erfunden. Es gibt 100 mehr als einen halben Jahrhundert. Aber ich habe Compiler geschrieben für MSP430, für ARM Cortex, M0, M3 und M4, MdMS in Planung. Und es gibt noch eine Variante, die zusammenarbeitend den Spurmann gemacht habe, die auf einem FPGA läuft. Aber das darf man ein bisschen mehr später. Eigentlich ist das ungewöhnlich, sie selbst vorzustellen, aber meine Freunde meinten, es sollte mal sein. Ich bin die Plump Physiker. Ich habe Physik mit dem Fach Gartenbau studiert. Ich habe eine Doktorarbeit in der Laser-Spektroskopie. Ich habe alle müssen uns kassend durcheinander, sondern das Radio-Navigation. Und meine Lieblingssprachen kann man sehen. Der Name macht sich etwas ungewöhnlich sein. Aber die erste unterstützte Plattform war der MSP430. Und von MSP und der Krieg, den französischen, kam der Name dann. Du beschreibst den MSP430. Falls er Ihnen drin ist, dann schreibt er direkt die Namen. Unterstützt dann alle MSP430-Landspässe, sehr viele ARM-Portex-Architekturen. Und für den FPGA wird ein bisschen mehr. Die klassischen Architekturen, also wie bis normalerweise implementiert worden ist durch Geschichte, war eine virtuelle Maschine, war eine Liste von Pointern drin war, wo nacheinander diese Pointer genommen worden sind und dann entweder wieder eine Liste von Pointern zierten oder aber eben eine Assembler-Premative. Natürlich ist das sehr schön, wenn man dann Fehler suchen möchte im Compiler. Das ist sehr einfach dadurch. Und es lassen sich auch einige ungewöhnliche Sachen dabei implementieren. Aber erst das viele, viele Taktzüge. Die ganz alten Systeme hatten sogar mal die Möglichkeit, noch einmal über eine Tabelle, die ganzen verschiedenen Pointer umzuleiten, so dass man Definitionen, die schon liefend, nachgerechnet auch ändern konnte. Also eine Definition ganz, ganz tiefen Systemen durch etwas Neues austauschen. Die wird dann sofort verwendet. Das ging mal. Außerdem lässt sich Fahrzeuge leicht dekompilieren, zumindest bei der klassischen Implementation, so dass bei einer Jupiter-Ace, man brauchte keine Qualitexte. Man hatte den Objektchord, man konnte ihn desassambieren, zurück in den Qualitext, ändern, neu kompilieren, fertig. Die Optimierungen, die ich jetzt vorführen werde, hören diesen interessanten Aspekt. Weil da Maschinenkurt raushandt und weil da auch Teile wegoptimiert werden. Es gibt also nicht mehr so die 1 zu 1 Zusammenhang zwischen dem, was man geschrieben hat und dem, was hinterher tatsächlich im Prozess ausgeführt wird. Anders herum jedoch, hatte fortlang auch mit dem Problem zu kämpfen, dass man das ein bisschen langsam gehalten hat. Das habe ich geändert. Und ich möchte gerne heute vorstellen, was für Optimierungen man im Ship selbst durchführen kann. Natürlich, aus der Compiler-Theorie heraus, sind das alles alte Hüte. Aber die meisten Compiler brauchen sehr viel Speiser, laufen auf dem PC, wo es erfasst und wie ganz davon gibt. Es wird aber mal herausfinden, welche Optimierungen man in dem Arbeitsbessern kleinen Mikro-Kontrollers implementieren kann. Das zugehören TLCOL, Konstantenzpeitung, Inlining, Operierung und Registallokation. In welcher Architektur, die Sie was implementiert haben, steht damit bei. Nun will ich die ganzen einzelnen Optimierungen einmal vorstellen. TLCOL ist relativ simpel. Wenn das letzte in einer Routine ein Callers und danach direkt an Vietnam kommt, dann kann man das auch durch einen Spunkbefehl ersetzen. Man braucht ja nicht den Umweg über den Sektion nehmen. Das ist eigentlich, weil klar, ist nichts Besonderes. Konstantenpeitung bedeutet, manchmal möchte man als Mensch etwas durchschreiben, ein paar Konstanten nehmen, sie multipliziert, zusammenverordert. All das, immer mitzukompilieren, wäre ja eigentlich Zeitverschwendung. Es steht ja schon während der Kompilation fest, was das Ergebnis dieser Berechnung sein wird. Der Compiler kann also durchaus diese Rechnung schon während des Kompilierens durchführen, nur noch das Ergebnis einkompilieren. Hier sieht man mal ein kleines Beispiel. Also 6 auf den Stack legen, 7 auf den Stack legen, beide Werte vertauschen, miteinander multiplizieren und das Ganze innen aufzumieren. Eigentlich sind die ersten Teile schon fest. Das reicht, wenn man 42 bloß kompilieren würde. Das ist die Konstantenpeitung. Das ist jetzt ein glasklarer Peil, wo man das direkt sieht. Aber manchmal gibt es auch aus anderen Optimierungen heraus noch die Möglichkeit, dass Konstantenpeitung möglich werden kann. Das ist ja nicht mehr so ganz so offensichtlich. Dazu, wie das implementiert wird, möchte ich erst mal kurz zeigen, wie der klassische Fortcompiler implementiert worden ist. Es war so, dass der Eingabestrom, den der Benutzter eingetippt hat in einzelner Wörter, wenn Token verhackt worden ist, dann wurde geprüft, ob es in der Liste der bekannten Definitionen auftaucht oder eben auch nicht. Ist das der Fall? Ist die Frage, ob kompiliert werden soll oder nicht? Gibt einen Ausführer und ein Kompiliermodus, seine interaktive Sprache? Im Kompiliermodus und wenn es nicht im Ideat ist, nach einer Spezialität von Fahrt, dann wird ein Aufrufen der Definitionen ein Kompilier, also ein Kohlbefehl geschrieben. Im Ideat bedeutet übrigens, dass etwas, was kompiliert werden soll, selbst ausgeführt wird. Das braucht man für Kontrollstrukturen, die dann noch so Sprüngehandel haben müssen und ihnen ist es. Und ansonsten ist man Ausführmodus, wird die Definition ausgeführt, nicht gefunden, versucht man es, als Teil zu interpretieren. Und sind nachdem auch kompiliert werden soll oder nicht, wird es auf den Stack gelegt oder es wird etwas kompiliert, was die Zahl dann bei der Ausführung auf den Stack legen wird. Es ist auch keine gültige Zahl, es ist ein Fehler. Um dort Konstantenpeitung einzufügen, sind keine so großen Änderungen nötig. Wichtig ist es eigentlich nur, dass man die Konstanten nicht kompiliert, zumindest nicht leicht, sondern erst mal sammelt und dann, wenn eine Operation kommt, die bei konstanten Eingaben auch konstante Ausgaben produziert, diese dann auszuführen. Die Änderungen sind so, dass jetzt ganz am Anfang der aktuellen Stack-Füllstand vermerkt werden muss, denn man muss auch wissen, wie viele Konstanten gerade zur Verfügung stehen. Steuers ausgeführt werden, wurde es gefunden, dann brauchen wir keine Konstantenpeitung machen und dann schmeißen wir den Fronten wieder weg, alles gut vergessen wird. Sind wir im Kompiliermodus, wird geprüft, ob diese Definition mit konstanten Eingaben auch eine konstante Ausgabe produzieren kann und der Label ist genug dafür vorhanden. Eine Invertierung an der Zahl braucht eine Konstante, eine Adition braucht zwei Konstanten und so weiter, das muss geprüft werden. Wenn das gut geht, kann sie ausgeführt werden. Sie lässt dann die Ergebnisse dort liegen und dadurch, dass wir wissen, wo das Stack-Pointer vorher gewesen ist, wissen wir auch, wie viele Konstanten danach noch auf dem Stack liegen geblieben sind. Es kann also durchaus variabel viele Ausgabekonstanten produzieren. Diese Definition ist jedoch nicht feinbar. Dann bleibt es nichts anderes übrig, dass alles, was an Konstanten dort liegt, einzukompilieren und dann einen klassischen Kohlbefehl zu machen. Ja, aber man kann den klassischen Kohlbefehl auch noch mal ein bisschen abwandeln. Man kann gucken, ob es eine sehr kurze Definition ist und einen Obkurs dann direkt einfügen und bei Partner natürlich immer wieder überprüfen. Das bedeutet, dass diese Definition selber um welche Bezahlfälle umsetzen kann. Nicht gefunden Zahlen bleiben, steht es auf dem Stack liegen, damit ich später in die Konstanten-Paltung reinkommen kann. Wichtig dabei ist, zu wissen, dass dabei, während die Zahlen gesammelt werden, ja schon ein Marker in den Stack gesetzt worden ist, um den Füllstand zu bestimmen. Ist es nicht als Zahl zu interpräzieren, das ist ein Fehler. Das ist ein Prozess, das ist ein Gedanke, um Konstanten-Paltung fortzumplementieren. Das hier ist grundsätzlich auf jeder Architektur möglich, wo fortläuft. Und es ist auch relativ unabhängig davon, wie das Fortjetzte und Einsinn drinnen implementiert ist. Ich habe schon gesehen, dass jemand Matthias Truttel von AMV für AVR angefangen hat, das auch einzubauen. Das noch zusammen rekommensieren soll. Es geht recht gut, es ist auch standardkonform. Die nächste Sache in Lightning. Klar, macht T-Compiler auch. Wir haben eine große Definitionen, die nur ein paar Obkurs haben können, mit einigen Vorsichtsmaßregeln, auch direkt eingefügt werden. Wozu sollte man einen Code hinschauen, wenn die Obkurs kürzer sind, dass der Code selbst. Und hier das Beispiel von Plus. Meine Mann ruft nicht die Prämitiven von Plus auf, weil man den Plus Obkurs direkt einfügen kann. Das leuchtet eines auch ein. Obkudierung, ich nenne es mal so, ich weiß nicht, wie es sonst genannt werden soll, ist, wenn ein Obkurs eine Konstante direkt in sich aufnehmen kann. Dann ist es doch sinnvoller, die Konstante direkt misstugobkudieren, als sie über den Spektrum zu legen und dann darüber zu verwenden. Man spart halt ein paar Takte und ein bisschen Plus. Das klingt davon ab, was für ein Prozessor man hat. Beim MSP430 geht das immer wunderbar. Bei einem Codex manchmal da hat nur einige Obkurs die Konstanten können. Und wenn man ein Spektrozessor hat, geht das gar nicht. Unter Registerallokatorer schließlich ist die Überlegung, dass man zwischen Ergebnisse, die bei Ford traditionell auf dem Spekt liegen würden, versucht auf Register abzubehen. Sein kleines Decksprach ist das ganz was anderes, als ein Prozessor, der hauptsächlich Registern arbeitet. Bei einem Codex ist das ganz besonders schlimm, denn er kann nicht direkt in den Speiser zugreifen, um da irgendwas zu berechnen, sondern er muss auf jeden Fall immer aus dem Speiser in Register holen, im Register etwas machen und in den Speiser zurückschreiben. Das ist ziemlich aufwendig. Wenn man das abkürsten kann, die Zwischenergebnisse gleich im Register hält, kann man viel kürstere Befehlstequenzen nutzen, die direkt zwischen den Registern arbeiten. Wichtig dabei ist noch, dass das Ganze transparent wird für den Programm. Wenn man also etwas macht, wo die logische Struktur des Stacks sichtbar wird oder sichtbar werden könnte, muss der Kompil auf jeden Fall zurückfallen und alles in den richtigen Stacks reinschreiben, sodass man dann auch direkt um Stack Manipulation machen kann, wenn das Thema notwendig ist. Das ist bei Ford ziemlich häufig. Bei Ford-Programm werden alle möglichen Tricks anwenden. Das Wesentliche für den Register-Lokator ist, zu wissen, wo welches Element gerade ist. Man muss also während der Kompilation ein Stack-Modell mitlaufen lassen, worin vermerkt ist, wo diese Stack-Elemente gerade sind. Sind sie noch auf dem Stack selbst, also im Arbeitsspeiser? Sind sie gerade in einem Register drin? Wenn da an welchem oder wenn neue Zwischenergebnisse auftreten, haben wir noch genug Register. Denn wenn mehr Zwischenergebnisse da sind, dass Register zur Verfügung stehen, dann müssen die Register wieder in den Arbeitsspeicher auf den Stack geschrieben werden. Und das ist das, was innen drin das Besondere ausmacht. Man kann es sehr klein implementieren. Aber, man muss daran denken, dass das sehr seltsam ist, wenn man mit dem Mikrocontroller läuft. Normalerweise gibt es bei Register-Lokatoren viele Algorithmen drumherum, die überlegen, wie man das möglichst gut über möglichst weite Strecken im Programm machen kann. Ich habe es sehr einfach gemacht. Bei den Stellen, wo Kontrollstrukturen verzweigen, hört man einfach auf. Man schreibt ein Eisnis-Deck und fertig. Das ist eine sehr simple Implementation. Und globale Optimierung habe ich gar nicht drin. Aber es ist ein Anfang. Das sind jetzt die Optimierungen, die angebrochen werden sollen. Nun will ich ein paar Beispiele dafür zeigen. Erst mal muss ich aber noch sagen, mit Chris Eis ist es nicht allein meine Arbeit, sondern basiert auf vielen, vielen anderen schönen Sachen, die auch vorgestellt worden sind. James Bowman hat in dort ein Prozessor entwickelt. Clifford Wolf, Fossin Sieb und Matthias Lasser haben die erste freie Touch-ins für FPGAs entwickelt. Und darauf basiert das alles. Darin habe ich die Konstantenfaltung, automatische Inline-Costa-Definition und T-Call Optimierung. Hier ist jetzt mal ein kleines Beispiel. Das ist noch aus der letzten Implementation, wie man über eine Leuchtschode kommunizieren kann. Für die, die es jetzt nicht bei der Assembly gesehen haben, ist es so, dass man eine Leuchtschode, die nicht nur zum Leuchten, sondern auch als Fotogrode nutzen kann. Und wenn man eine Schnee-Internat abwechselt, leuchten und gucken, wie hell es ist, hat man eine generelle Schnittstelle über eine Leuchtschode. Das ist natürlich auch dazu für, wenn man den Kompil auch noch im Ship hat, dann kann man über die Power-On-Lampe seiner Kaffeemaschine neue Prübprogramme ein, Speiser- und Fehlermeldung auslesen. Aber das ist jetzt noch was anderes, nur so nebenan. Rufen wir uns das jetzt mal genau an. Erstens werden Konstanten definiert für Anode und Cthode, wo die gerade angeschlossen sind. Und dann eine Definition sein soll sie heißen, wo die Anode und die Cthode bei der Ausgang gesetzt werden und die Anode heim. Wenn man sich das jetzt mal disassimpliert angeht, ist das schon einiges passiert. Als erstes anode-Cthode-A ist zu einer einzigen Konstantie Hex-11 zusammengepasst worden. Das war die Konstanten-Faltung. Dann, als nächstes, ganz unten. Das letzte wäre ein Call um etwas zu speichern im ERO-Teil. Dort wurde jetzt ein Call und kein Call eingefügt. Das war die Take-Call Optimierung. Das ist soweit noch ganz klar. Hier kann man noch einmal das Inlining sehen. Denn an der Stelle hier, Cthode-N, das End wurde auch direkt eingefügt, das Aluo-Prot und wurde nicht als Call eingefügt. Und dann darum herum natürlich die üblichen Verdächtigen Gründen, passiert Take-Call. Und für die Konstanten-Faltung habe ich noch ein kleines Beispiel. Das war das, was ich ganz am Anfang hatte, wie das aussieht. Ganz einfach. Das ist vom Compiler. Schon während das Kompilieren. Die Konstante wird geschrieben. Ein Stack-Prozessor kann keine Konstanten im Obkurs mit einbauen. Also gibt es da keine weitere Optimierung mehr. Dann kommt Plus. Plus ist drin im Prozessor. Und der J1 hat noch die Möglichkeit, auch gleich den Rückbruch mit im Obkurs zu haben. Fertig. Take-Call im Prinzip auch erledigt. So. Zum J1-Prozessor kann man vieles zählen. Das ist unverständlich. Das sind 200 Teilen V-Log. Das lohnt sich wirklich, sich das mal anzugucken. Fert mal rein, wenn ihr euch dafür interessiert. MSP430. Das ist ein Prozessor, der sehr viele verschiedene Adressierungsarten unterstützt und auch eigentlich richtig gut sofort passt. Mit Take-Call gab es ein paar Probleme, weil es einiges richtig gibt, die mit den Rückbruchadressen was machen und dann nackst das. Also habe ich keinen Take-Call drin. Aber Konstanten-Faltung, wir haben ein paar Reispiele. Hier kann man wieder sehen, es werden Konstanten definiert und ganz am Ende sollen dann wieder Leuchten angesteuert werden und so der Taster vorbereitet werden. Das ist einfach nur Initialisierung für so ein Launchpad. Das sieht kompiliert so aus. Jetzt wird mehrere Sennationen. Die Konstanten kommen wieder über die Konstanten-Faltung und diese Befehle werden über Inlande eingebaut. Und dadurch, dass wir direkt Parameter in den Obbrut übernehmen können, kriegen Sie auch die Obprudierungen mit. Sodass das, was hinterher rauskommt, eines der gleiche ist, was ich auch nach dem Lasch schreiben würde. Das kann ich auch immer. Die pfeilen wir nur ein Obbrut. Das war's. Das lässt das übrigens der Rücksprung. Der sieht man ein bisschen komisch aus, aber das funktioniert. Mikris de Laris ist eine direkte Portierung von Mikris und der ist wieder gewesen. Der Laris Launchpad war die erste Plattform, die unterstützt war der. Der Name Klinghurt habe ich so gelassen. Eigentlich ist es identisch mit dem MSP430, wenn es um Optimierung geht. Aber ich habe jetzt gerade noch, das ist nur noch fertig geworden, ein Registallokator reinbekommen. Den möchte ich noch kurz zeigen. Hier sieht man ein Beispiel, das schon ein bisschen schwieriger ist. Das oben ist der Graykurt. Der Graykurt ist so eine Sache, warum soll es jetzt aber nicht gehen? Dann dann darum, dass man hier sieht, dass keine Stackbewegungen mehr da sind. Das oberste Stack Element, das im Armenregister 6 enthalten und die Zwischenergebung, also duplikätig das oberste Element nochmal auf den Stack, dann kommt hier eins. Man sieht schon, der Siebebefehl hat als Zielregister einen anderen Register, also einen freien Zwischenergebungsregister und exklusiv oder nimmt es von da, und das wieder auf das oberste Stacklement, so dass man gar keine Stackbewegung mehr brach. Und das Quadrat, genau so, das ist eben die Sache, dass man versucht, Zwischenergebungsregistern zu halten, so weit möglich. Das hier ist ein klein bisschen aufwendigeres Beispiel. Hier ist es so, dass Labeln geholt werden sollen, zwei Stück, aber wir zurückzuschieben. Im Arm Cortex kann man übrigens einen Offset an den Ladebefehl dranführen. Also, der Wachsabel ist geladen, dann wird die erste Wachsabel geholt, dann die Zweifel, beide werden radiert und zurückzuschieben. Wieder keine Stackbewegung löte, der jetzt ein bisschen neugierig geworden ist und sofort loslegen möchte. Alle Launchpads von Texas Instruments werden unterstützt. Der Arm Cortex, viele davon von STM, Texas Instruments, Infine, Neuerdings und Spielscare. Und wer andere Systeme benutzt, kann natürlich auch gerne Fahrt ausprobieren. Es gibt G-Fahrt für den PC, AM-Fahrt für die ASME-AVR-Reihe, für PIC gibt es Flash-Fahrt und für den VAT-80 und noch einige andere Kamelfahrt. Ganz, ganz viele verschiedene. Es kommt nämlich daher, dass dadurch das Fahrt recht klein ist und recht leicht implementiert werden kann. Dass viele Leute zum Kennenlernen der Sprache einfach selber ihren eigenen Compiler und erst mal Spaß. Und ich denke, auch wenn man mir jetzt dafür den Kopf abreißen würde in einigen Kreisen, man möge es tun. Denn dabei erlernt man sehr viele, was ist innere Kennen. Andere sagen natürlich, man soll sich erst mal mit der Philosophie das Sprach auseinandersetzen. Weitere Seiten haben wir so einen guten Argument. Ich muss sagen, ich hab direkt mit dem schreiben meinen ersten Compiler begonnen und den und ja. Das ist das, was man mit den Analog-Digitalwander, der ein Temperatursensor trägt. Das ist einfach nur eine kleine Schleife, die 16-mal durchläuft und es wird jeweils aus dem Analog-Kanal 10 im MST 430 ein Wert gelesen. Das unterste Bit wird maskiert. Dann hinzugetan zu dem, was man schon hat und das nächste Bit. Das ist jetzt, wie es kompiliert worden ist. Als erstes werden die Schleifenregister freigemacht. Wenn man eine Null auf den Stack gelegt, wenn man sich das hier noch mal anguckt, eine Null ganz am Anfang wurde da ja schon hingelegt. Also der Wert, wo dann hinter die Bit aus dem AD-Wander reinkommen. Dann, der Schiffsbefehl wurde bei Inline nicht eingefügt. Dann kommt die konstante 10 auf den Stack. Leider gibt es nur einen Pustbefehl im MST 430. Also die Kombination aus Stack-Pointer oder in die Regen was drauflegen. Das wird mit einem Fallbefehl und anschließend wieder Inleinig und Obkordierungen. Das Maskieren des unteren Bit ist nur noch ein Obkord. Ich sage genau so, kann direkt eingefügt werden. Dann wird der Schleifenfehl erhöht, verglichen und die Schleife springt zurück. Wenn die Schleife fertig ist, Registers zurückholen, Rücksprung. Hier hat man mal die ganzen Optimierung alle in eins gesehen, wie das so in einem echten Beispiel aussieht. Das ist mein etwas größeres Beispiel auf dem Armkartex. Die Bit-Exponenzteilfunktion ist sowas wie eine Exponenzteilfunktion, aber auf Intelsassfunktion. Da kann man auch noch mal verschiedene Sachen sehen, wie das im Armkartex ausgeht und was passiert, wenn Kontrollstrukturen dazwischenkommen. Kannst du am Anfang vergleichen, ob der Wert an bestimmte Größe erreicht hat. Dann dieses Pust-LA kommt daher, dass im Armkartex so ein Link-Register existiert, der dafür da ist, dass Unterprogrammeinsprühen, die keine weitere Ebene haben, direkt im Register bleiben und nicht auf dem Visanz dargelegt werden müssen. Wenn aber Kontrollstrukturen kommen und man noch nicht klar ist, ob in einem der Zweige vielleicht doch noch ein Unterprogramm aufgerufen werden muss, muss er jetzt gesichert werden. Dann folgt der Sprung, der zur Üff gehört, eine Zahl wird runtergeworfen, ein Ladebefehl ist, weil der Register Top-of-Sex ohnehin schon die ganze Zeit bereit gelegen hat. Im S-Bike sind ein bisschen mehr zu tun. Das duktlich kehrt, brauchen wir nicht, ein Registerarmkarteer dahinter. Dann der Vergleich wieder das ist. Hier bei allen 4 Schiffs kann man wieder sehen, dass das alles in einem Opus zusammengefügt worden ist. Das ist wieder Kombination aus Konstantenfaltung und Inleinung. Dann der S-Bike. So, hier ist jetzt ein bisschen mehr zu tun. Man kann jetzt auch sehen, dass wir es mir in der Zwischenregister auftreten. Also R3 und R2, beide mit dabei. Und die Werte werden jetzt nicht auf das Deckel legt, sondern zwischen den Registern hin und her geschoben. Vielleicht wird das jetzt ein bisschen unübersichtlich, aber ich denke, wenn man das nochmal direkt vergleicht, ich habe hier immer dort, wo Assemblers steht, auch die Fortspray Texte daneben muss etwas für die Zeile generiert werden. Was man hier noch sehen kann, dass man im Abend Vortex leider nicht eine Konstante in den Endbefehlungen einflügen kann. Deswegen, dass jetzt über einen anderen Register geladen wird. Aber andere Sachen, wie der Schiffsbefehl, können Konstanten direkt übernehmen. Das ist ja passiert. Und dann am Ende muss aufgeräumt werden. Bislang war das kein Problem, weil das oberste Element immer in R6 geblieben ist. Das ist aber, wurden durch die Zwischenergebnisse von das hin und her rangieren, der Fall erreicht, dass das oberste Element auf dem Steck eben nicht mehr in dem Register, der normalerweise das oberste Element trägt. Deswegen, der volleste Befehl, der Mufbefehl dient zum Aufräumen. Der hat kein Equivalent in Fahr. Aber er dient dazu, das Deckmodell, was gerade in einem Zustand ist, wie es sonst nicht sein sollte, wieder auf den kanonischen Steck zurückzuführen, was so übergeben werden kann. Für gemerkt, globaler Optimierung gibt es noch nicht. Wird es wohl auch erst mal nicht geben. Aber man kann soweit schon mal sehen, dass man da die gesamte Sache ohne Speckbewegung geschafft hat. Weiter von abgesehen, dass der Vitaunstag einmal die Adresse zum Rückpunkt aufgenommen hat, was er aber nicht vermeiden konnte, weil dieser Compiler sei nicht vorausschauern kann. Er kann immer nur sehen, wer gerade ist und versuchen dafür zu generieren. Um das weglassen zu können, müsste man dann vorausschauern können, um zu sehen, was in den Kontrollstruck führt und vielleicht doch noch passiert. Damit bin ich am Ende angelangt. Alle Beispiele gefällt. Kann ich nur noch wünschen, alles Gute zum neuen da. Und wenn noch Fragen sind, kommt gleich noch mal zu mir. Schreibt mir, ich freue mich über viele E-Mails. Vielen Dank. Alles klar. Vielen Dank.