Speichern und Aufrufen einer kompilierten Funktion in C / C ++

Für Optimierungszwecke auf sehr niedriger Ebene wäre es für mich nützlich, wenn ich eine kompilierte Funktion direkt in einer Variablen speichern könnte.nicht ein Zeiger auf eine Funktion. Das heißt, wenn ich eine Funktion foo habe, möchte ich einen char-Puffer groß genug machen, um die für foo generierten Maschinenanweisungen aufzunehmen, und dann in der Lage sein, foo tatsächlich aufzurufen, indem ich C irgendwie anweise, die Ausführung zum Inhalt dieses Puffers zu springen (Nehmen wir an, ich habe einen eigenen Compiler, um sicherzustellen, dass der Zeichenpuffer für meine Architektur richtig ausgerichtet ist). Idealerweise würde ich dies gerne tun, um den Montageaufwand auf ein Minimum zu beschränken (mir ist klar, dass einige erforderlich sein könnten).

Meine bisher beste Lösung wäre, ein Programm zu kompilieren, das genau die Funktion hat, die ich mit GCC zusammenstellen möchte, dann in Maschinencode zu kompilieren, dann die Adressen aus der ausgegebenen Baugruppe zu verwenden, um den gewünschten Maschinencode aus der ausführbaren Datei zu extrahieren und dann manuell auszufüllen den Puffer mit dem in meinem Programm, dann Inline-Assembly verwenden, um an die Startadresse des Puffers zu springen. Das ist hackiger und manueller als ich es gerne hätte.

Ich muss keine neuen Funktionen zur Laufzeit kompilieren, sondern muss nur Anweisungen im Puffer enthalten, die verschiedenen bereits kompilierten Funktionen zur Laufzeit entsprechen. Z.B. Ich könnte 3 kompilierte Funktionen und 1 Puffer haben. Die 3 Funktionen sind zur Kompilierungszeit bekannt, aber zur Laufzeit kann der Puffer einer der 3 Funktionen zu unterschiedlichen Zeiten entsprechen.

Bearbeiten: Um zu klären, was zu gewinnen wäre: Ich habe eine Struktur, deren Mitglied dieser Puffer sein wird, und verschiedene Zeiger auf Instanzen dieser Struktur. Der Puffer jeder Struktur kann eine andere kompilierte Funktion enthalten. Wenn ich einen Funktionszeiger anstelle des Puffers verwenden würde, müsste ich den Funktionszeiger der Struktur laden und dann den Funktionszeiger deref. Mit dem Puffer kann ich den Programmzähler einfach auf einen Versatz (die relative Position des Puffers) der Basis der Struktur springen. Es ist eine Stufe weniger Indirektion. Für sehr kleine Funktionen kann dies eine Einsparung sein.

Edit 2: Weitere Klarstellung:

Mit einem Funktionszeiger:

Zeiger aus & struct + offsetof (Zeiger) ladenSpringe zur im Zeiger enthaltenen Stelle

Mit einem Puffer, der Maschinencode enthält:

Springe zu & struct + offsetof (buffer)

Der zweite ist weniger Schritte.

Antworten auf die Frage(12)

Ihre Antwort auf die Frage