Ich versuche, meine eigene JIT zu erstellen und bis jetzt geschafft, sehr einfachen Assembly-Code (in Maschinen-Code) zu laufen, aber Probleme herauszufinden, wie man Funktionen auf diese Weise aufrufen. In Visual Studio kann ich Funktionen im Disassemblierungsfenster sehen.Call-Funktionen von x86_64 Assembly
Eine andere verwandte Frage ist, wie ich Win32 MessageBox() in Maschinencode aufrufen?
Nächste Frage ist, wie ich externe DLL/LIB-Funktionen auf diese Weise aufrufen?
Gibt es auch Bücher oder Tutorials, die mich in diesem Thema weiterbringen könnten? Ich habe versucht, danach zu suchen, aber Ergebnisse wie .NET, JVM und LLVM zu bekommen, die ich glaube nicht wirklich, was ich suche.
Hier ist eine vereinfachte Version des Codes, arbeite ich an:
#include <iostream>
#include <Windows.h>
int main(int argc, char* argv[])
{
// b8 03 00 00 00 83 c0 02 c3
unsigned char code[] = {
0xb8, // mov eax, 3
0x03, 0x00, 0x00, 0x00, // 3 (32 bit)
0x83, // add eax, 2 // 0x83 = add,
0xc0, // ModR/M with immediate 8 bit value
0x02, // 2 (8 bit)
0xc3 // ret
};
void* mem = VirtualAlloc(0, sizeof(code), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(mem, code, sizeof(code));
DWORD old;
VirtualProtect(mem, sizeof(mem), PAGE_EXECUTE_READ, &old);
int(*func)() = reinterpret_cast<int(*)()>(mem);
printf("Number is %d\n", func());
VirtualFree(mem, 0, MEM_RELEASE);
return 0;
}
Ist es möglich, den JIT-Assembler-Code zu haben, eine C++ Funktion aufzurufen?
Vor diesem Projekt habe ich einen Byte-Code-Interpreter in C++ erstellt, aber ich war nicht wirklich glücklich mit der Geschwindigkeit beim Vergleich mit äquivalenten Testprogramm in C#. C# war ungefähr 25x schneller. Also bin ich auf etwas namens JIT gestoßen, um es schneller zu machen. Ich hoffe, Sie alle können sehen, wo ich dieses JIT-Projekt nehme. Und wenn möglich, sollte es mit der GUI umgehen.
Natürlich ist es möglich. Gazillion Beispiele herum, vielleicht ein Blick auf eine [Hallo Welt] (http://Stackoverflow.com/a/1032422/547981) für den Anfang. Die Montage per Hand wird jedoch nicht viel Spaß machen. Beachten Sie, dass Funktionsaufrufe wahrscheinlich nicht Ihr Engpass sind. – Jester
Ich schreibe in der Regel ein Beispielprogramm in C/C++, dann haben Sie den Compiler Ausgabe Assembly-Code, um die Assembly-Level-Namen und Aufrufreihenfolge zu bekommen. Im Fall von Visual Studio 2015 ist printf jetzt Teil einer Include-Datei, was bedeutet, dass es effektiv mit C/C++ - Code verknüpft wird. Eine Möglichkeit, dies zu umgehen, ist ein Projekt, das eine C-Datei für printf und eine Assemblydatei für den Rest des Projekts enthält. Möglicherweise gibt es eine Option, um bestimmte Bibliotheken zu importieren, die noch den alten Stil printf enthalten. – rcgldr
Nun, IIRC, es ist möglich, clang zu kompilieren, um C-Quelle in Speicher zu kompilieren, und dann JIT es von LLVM in Maschinencode und führen Sie es aus, so LLVM-Quellen erhalten Sie wahrscheinlich Ihre Antworten .. in wenigen Jahren ... Es ist Auch ist mir unklar, warum Sie von der Sprachgeschwindigkeit geärgert werden, schreiben Sie einfach Performance-Teile in C++ und Assembly, der JIT wird im besten Fall im besten Fall kaum gleichwertig sein, und in jedem richtig gestimmten Performance-Fall nicht. Für nicht leistungskritische Teile sollte der 25x auch keine Rolle spielen. Obwohl dies eine gute Übung sein kann, um herauszufinden, wie cool C++ ist. :) – Ped7g