从x86_64程序集调用函数

时间:2017-02-01 22:57:43

标签: c++ assembly x86-64 jit machine-code

我正在尝试创建自己的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。

1 个答案:

答案 0 :(得分:0)

您可能会找到一些关于编写编译器/链接器的教程。它可能有助于实现/调用动态库。

我不确定你通过调用C ++函数究竟是什么意思。无论如何,我写了下面的演示程序,你可以看看它是否有用。

#include <Windows.h>
#include <iostream>


using namespace std;

__int64 sub(__int64 a, __int64 b)
{
    return a - b;
}

int main(int argc, char **argv)
{
    char code[] =
    {
        0x48, 0x89, 0xC8,           // mov rax, rcx
        0xC3,                       // ret

        0x48, 0x83, 0xEC, 0x20,     // sub rsp, 0x20
        0xFF, 0xD0,                 // call rax
        0x48, 0x83, 0xC4, 0x20,     // add rsp, 0x20
        0xC3                        // ret
    };


    char *mem = static_cast<char *>(VirtualAlloc(0, sizeof(code), MEM_COMMIT, PAGE_EXECUTE_READWRITE));

    MoveMemory(mem, code, sizeof(code));

    auto setFunc = reinterpret_cast<void *(*)(void *)>(mem);
    auto callFunc = reinterpret_cast<__int64 (*)(__int64, __int64)>(mem + 4);

    setFunc(sub);
    __int64 r = callFunc(0, 1);
    cout << "r = " << r << endl;

    VirtualFree(mem, 0, MEM_RELEASE);


    cin.ignore();
    return 0;
}
相关问题