Je suis en train de créer mon propre JIT et j'ai réussi à exécuter un code d'assemblage très simple (en code machine), mais j'ai du mal à comprendre comment appeler les fonctions de cette manière. Dans Visual Studio, je peux voir les fonctions dans la fenêtre de désassemblage.Fonctions d'appel de l'assembly x86_64
Une autre question connexe est comment puis-je appeler Win32 MessageBox() en code machine?
La question suivante est comment puis-je appeler des fonctions DLL/LIB externes de cette manière?
Y a-t-il aussi des livres ou des tutoriels qui pourraient m'apprendre davantage sur ce sujet? J'ai essayé de le rechercher mais obtenir des résultats comme .NET, JVM et LLVM qui je pense n'est pas vraiment ce que je cherche.
Voici une version simplifiée du code que je travaille sur:
#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;
}
Est-il possible d'avoir le code assembleur JIT pour appeler une fonction C++?
Avant ce projet j'ai fait un interpréteur de code octet en C++, mais je n'étais pas vraiment content de la vitesse en le comparant à un programme de test équivalent en C#. C# était environ 25 fois plus rapide. Donc je suis tombé sur quelque chose appelé JIT pour le rendre plus rapide. Donc j'espère que vous pouvez tous voir où je prends ce projet JIT. Et peut-être si possible, faites-le gérer l'interface graphique.
Bien sûr, c'est possible. Exemples Gazillion autour, peut-être regarder un [bonjour monde] (http://stackoverflow.com/a/1032422/547981) pour les débutants. L'assembler à la main ne sera pas amusant. Notez que les appels de fonction sont peu susceptibles d'être votre goulot d'étranglement. – Jester
J'écris généralement un exemple de programme en C/C++, puis j'ai le code de l'assemblage de sortie du compilateur afin d'obtenir les noms de niveau d'assemblage et la séquence d'appel. Dans le cas de Visual Studio 2015, printf fait maintenant partie d'un fichier d'inclusion, ce qui signifie qu'il est effectivement intégré au code C/C++. Une façon de gérer cela est d'avoir un projet qui inclut un fichier C pour le printf, et un fichier d'assemblage pour le reste du projet. Il peut y avoir une option pour importer des bibliothèques spécifiques qui incluent toujours l'ancien style printf. – rcgldr
Eh bien, IIRC, il est possible de plier clang pour compiler la source C en mémoire, puis le mettre par LLVM dans le code machine et l'exécuter, donc en étudiant les sources LLVM vous obtiendrez probablement vos réponses ... dans quelques années ... C'est Je ne comprends pas non plus pourquoi vous êtes gêné par la vitesse du langage interprété, écrivez simplement des parties de performance en C++ et en assembleur, le JIT sera généralement à peine dans le meilleur des cas et sous-performera dans n'importe quel cas de performance. Pour les pièces critiques non performantes, le 25x ne devrait pas non plus avoir d'importance. Bien que cela puisse être un bon exercice pour vous faire comprendre à quel point C++ est cool. :) – Ped7g