虚拟机如何实时生成本地机器码并执行?
假设你已经知道要发出哪些本地机器操作码,那么你该如何实际运行它呢?
是通过将助记符指令映射到二进制代码,将其填充到 char* 指针中并将其强制转换为函数并执行的hacky方法吗?
还是会生成临时共享库 (.dll 或 .so 或其他) 并使用标准函数 (例如 LoadLibrary
) 将其加载到内存中?
虚拟机如何实时生成本地机器码并执行?
假设你已经知道要发出哪些本地机器操作码,那么你该如何实际运行它呢?
是通过将助记符指令映射到二进制代码,将其填充到 char* 指针中并将其强制转换为函数并执行的hacky方法吗?
还是会生成临时共享库 (.dll 或 .so 或其他) 并使用标准函数 (例如 LoadLibrary
) 将其加载到内存中?
如果你是在使用C或C++(或类似语言)进行操作,那么你需要做的就是将助记符指令映射到二进制代码中,将其塞入char*指针并将其强制转换为函数并执行。
是的,如果你使用C或C++(或类似语言)进行操作,这正是你需要做的。
看起来很“hacky”,但这实际上是语言设计的产物。请记住,你想要使用的算法非常简单:确定要使用的指令,将它们加载到内存中的缓冲区中,并跳转到该缓冲区的开头。
然而,如果你真的想这样做,请确保在返回到C程序时正确获取调用约定。如果我想生成代码,我会寻找一个能为我处理这个方面的库。Nanojit最近被报道过,你可以查看一下。
是的。您只需构建一个char*并执行它即可。但是,您需要注意一些细节。char*必须位于可执行内存部分,并且必须具有适当的对齐方式。
除了nanojit外,您还可以查看LLVM,这是另一个库,能够将各种程序表示编译为函数指针。它的接口干净,生成的代码往往高效。
void (*MyFunc)() = (void (*)()) VirtualAlloc(NULL, sizeofblock, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
//Now fill up the block with executable code and issue-
MyFunc();