Ich habe eine virtuelle Maschine in C geschrieben, die für eine Nicht-JIT-VM eine ordentliche Leistung hat, aber ich möchte etwas Neues lernen und die Leistung verbessern. Meine derzeitige Implementierung verwendet einfach einen Schalter zur Übersetzung von VM-Bytecode in Anweisungen, die in eine Sprungtabelle kompiliert werden. Wie ich sagte, anständige Leistung für das, was es ist, aber ich habe eine Barriere, die nur mit einem JIT-Compiler überwunden werden kann getroffen.
Ich habe vor nicht allzu langer Zeit schon einmal eine ähnliche Frage zur Selbstmodifizierung von Code gestellt, aber mir wurde klar, dass ich nicht die richtige Frage gestellt hatte.
Mein Ziel ist es also, einen JIT-Compiler für diese virtuelle C-Maschine zu schreiben, und zwar in x86-Assembler. (Ich verwende NASM als mein Assembler) Ich bin nicht ganz sicher, wie ich das anstellen soll. Ich kenne mich mit Assembler aus und habe mir einige Beispiele für selbstmodifizierenden Code angesehen, aber ich habe noch nicht herausgefunden, wie man Code generiert.
Mein Hauptproblem ist bisher das Kopieren von Anweisungen in einen ausführbaren Speicherbereich, avec meine Argumente. Ich weiß, dass ich eine bestimmte Zeile in NASM markieren und die gesamte Zeile von dieser Adresse mit den statischen Argumenten kopieren kann, aber das ist nicht sehr dynamisch und funktioniert nicht für einen JIT-Compiler. Ich muss in der Lage sein, die Anweisung aus dem Bytecode zu interpretieren, sie in den ausführbaren Speicher zu kopieren, das erste Argument zu interpretieren, es in den Speicher zu kopieren, dann das zweite Argument zu interpretieren und es in den Speicher zu kopieren.
Ich habe mich über mehrere Bibliotheken informiert, die diese Aufgabe erleichtern würden, wie GNU lightning und sogar LLVM. Ich möchte dies jedoch zuerst von Hand schreiben, um zu verstehen, wie es funktioniert, bevor ich externe Ressourcen verwende.
Gibt es irgendwelche Ressourcen oder Beispiele, die die Community zur Verfügung stellen könnte, um mir den Einstieg in diese Aufgabe zu erleichtern? Ein einfaches Beispiel, das zeigt, wie zwei oder drei Anweisungen wie "add" und "mov" verwendet werden, um ausführbaren Code mit Argumenten dynamisch im Speicher zu erzeugen, würde Wunder bewirken.