【发布时间】:2017-06-18 21:15:38
【问题描述】:
我正在尝试创建自己的 JIT,到目前为止,我设法运行了非常简单的汇编代码(在机器代码中),但是在弄清楚如何以这种方式调用函数时遇到了麻烦。在 Visual Studio 中,我可以在反汇编窗口中看到函数。
另一个相关问题是如何在机器码中调用 Win32 MessageBox()?
下一个问题是如何以这种方式调用外部 DLL/LIB 函数?
还有任何书籍或教程可以进一步教我这个主题吗?我试图搜索它,但得到的结果如 .NET、JVM 和 LLVM,我认为这并不是我真正想要的。
这是我正在处理的代码的简化版本:
#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;
}
是否可以让 JIT 汇编代码调用 C++ 函数?
在这个项目之前,我用 C++ 制作了一个字节码解释器,但是在将它与 C# 中的等效测试程序进行比较时,我对它的速度并不满意。 C# 大约快 25 倍。所以我偶然发现了一种叫做 JIT 的东西来让它更快。所以我希望你们都能看到我把这个 JIT 项目带到了哪里。如果可能的话,也许让它处理 GUI。
【问题讨论】:
-
当然可以。周围有无数的例子,也许可以先看看hello world。不过,手工组装不会很有趣。请注意,函数调用不太可能成为您的瓶颈。
-
我一般用C/C++编写一个示例程序,然后让编译器输出汇编代码,以获得汇编级别名称和调用顺序。对于 Visual Studio 2015,printf 现在是包含文件的一部分,这意味着它可以有效地与 C/C++ 代码内联。解决此问题的一种方法是创建一个项目,其中包含一个用于 printf 的 C 文件,以及一个用于项目其余部分的程序集文件。可以选择导入仍包含旧式 printf 的特定库。
-
好吧,IIRC,可以弯曲clang将C源代码编译到内存中,然后通过LLVM将其JIT成机器代码并运行它,因此通过研究LLVM源代码,您可能会得到答案。几年后......我也不清楚为什么你会被解释语言的速度所困扰,只是用 C++ 和汇编编写性能部分,JIT 在最好的情况下通常很难达到标准,并且在任何适当调整的性能情况下表现不佳.对于非性能关键部件,25 倍也不重要。尽管这可能是一个很好的练习,可以让您了解 C++ 有多酷。 :)
标签: c++ assembly x86-64 jit machine-code