Question

Comment fonctionne une machine virtuelle générer du code machine natif à la volée et l'exécuter?

En supposant que vous pouvez comprendre ce que sont la machine natif op-codes que vous souhaitez émettre, comment allez-vous réellement de course il?

Est-ce quelque chose que hacky cartographie des mnémoniques des instructions de codes binaires, la farce dans un char* pointeur et de la coulée comme une fonction et de l'exécution?

Ou voulez-vous générer un temporaire de la bibliothèque partagée (.dll ou .donc, ou autre) et de le charger dans la mémoire à l'aide des fonctions standard telles que LoadLibrary ?

Était-ce utile?

La solution

Vous pouvez simplement faire l' compteur de programme pointez sur le code que vous voulez exécuter.Rappelez-vous que les données peuvent être des données ou du code.Sur x86, le compteur de programme est le registre EIP.L'adresse IP de la partie de l'EIP est synonyme de pointeur d'instruction.L'instruction JMP est appelé à passer à une adresse.Après le saut de l'EIP contiendra cette adresse.

Est-ce quelque chose que hacky cartographie des mnémoniques des instructions de codes binaires, la farce dans un char* pointeur et de la coulée comme une fonction et de l'exécution?

Oui.C'est une façon de le faire.Le code résultant serait jetée d'un le pointeur de fonction dans C.

Autres conseils

Est-ce quelque chose que hacky cartographie des mnémoniques des instructions de codes binaires, la farce dans un char* pointeur et de la coulée comme une fonction et de l'exécution?

Oui, si vous étiez à le faire en C ou C++ (ou quelque chose de similaire), c'est exactement ce que vous souhaitez faire.

Il semble hacky, mais qui est en fait un artefact de la langue de conception.Rappelez-vous, l'algorithme réel que vous voulez utiliser est très simple:déterminer quelles instructions vous souhaitez utiliser, de les charger dans un tampon en mémoire, et de sauter au début de la mémoire tampon.

Si vous essayez vraiment pour ce faire, cependant, assurez-vous que vous obtenez la convention d'appel de droite lorsque vous revenez à votre programme C.Je pense que si je le voulais pour générer le code j'aurais l'air d'une bibliothèque, de prendre soin de cet aspect pour moi.Nanojit de l'été dans les nouvelles récemment;on pourrait y voir.

Yup.Vous venez de construire un char* et de l'exécuter.Cependant, vous avez besoin de noter quelques détails.Le char* doit être dans un fichier exécutable section de la mémoire et doit avoir un bon alignement.

En plus de nanojit vous pouvez aussi consulter les LLVM qui est d'une autre bibliothèque qui est capable de compiler un programme représentations vers le bas à un pointeur de fonction.Son interface est propre et le code généré a tendance à être efficace.

Autant que je sache, il compile tout en mémoire parce qu'il a à exécuter certaines heuristiques afin d'optimiser le code (c'est à dire:inline au fil du temps), mais vous pouvez jeter un oeil à la Source Partagée Common Language Infrastructure 2.0 rotor de presse.L'ensemble de la base de code est identique .NET, sauf pour la Gigue et la GC.

Ainsi que le Rotor 2.0 " - vous pouvez aussi jeter un oeil à la HotSpot de la machine virtuelle dans l'OpenJDK.

À propos de générer une DLL:supplémentaires requis I/O pour que, en plus de la liaison, en plus de la complexité de la génération de la DLL format, le rendrait beaucoup plus compliquer, et surtout qu'ils tueraient les performances;en outre, à la fin, vous avez encore appeler une fonction pointeur vers le code chargé, donc...Aussi, compilation JIT peut se passer d'une méthode à la fois, et si vous voulez faire ce que vous feriez générer beaucoup de petites Dll.

À propos de la "exécutable section" exigence, l'appel de mprotect() sur les systèmes POSIX peut réparer les autorisations (il y en a un similaire API Win32).Vous avez besoin de le faire pour un grand segment de mémoire au lieu qu'une fois par méthode, car il serait trop lent autrement.

Sur la plaine x86 vous ne remarquent pas le problème, sur x86 avec PAE ou 64 bits AMD64 et Intel 64 bits des machines, vous obtiendrez une erreur de segmentation.

Est-ce quelque chose que hacky que la cartographie les mnémoniques des instructions binaires codes, la farce dans un char* pointeur et de la coulée comme une fonction et de l'exécution?

Oui, ça marche.

Pour ce faire, dans windows, vous devez définir PAGE_EXECUTE_READWRITE pour le bloc alloué:

void (*MyFunc)() = (void (*)()) VirtualAlloc(NULL, sizeofblock,  MEM_COMMIT, PAGE_EXECUTE_READWRITE);

//Now fill up the block with executable code and issue-

MyFunc();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top