Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从x86_64程序集调用函数_C++_Assembly_X86 64_Jit_Machine Code - Fatal编程技术网

C++ 从x86_64程序集调用函数

C++ 从x86_64程序集调用函数,c++,assembly,x86-64,jit,machine-code,C++,Assembly,X86 64,Jit,Machine Code,我正在尝试创建自己的JIT,到目前为止,我已经成功地运行了非常简单的汇编代码(机器代码),但是在弄清楚如何以这种方式调用函数时遇到了困难。在VisualStudio中,我可以在反汇编窗口中看到函数 另一个相关问题是如何在机器代码中调用Win32 MessageBox() 下一个问题是如何以这种方式调用外部DLL/LIB函数 还有什么书或教程可以进一步教我这门课吗?我尝试过搜索它,但得到了像.NET、JVM和LLVM这样的结果,我认为这并不是我真正想要的 下面是我正在编写的代码的简化版本: #in

我正在尝试创建自己的JIT,到目前为止,我已经成功地运行了非常简单的汇编代码(机器代码),但是在弄清楚如何以这种方式调用函数时遇到了困难。在VisualStudio中,我可以在反汇编窗口中看到函数

另一个相关问题是如何在机器代码中调用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;
}
#包括
#包括
int main(int argc,char*argv[])
{
//b8 03 00 00 83 c0 02 c3
无符号字符代码[]={
0xb8,//mov-eax,3
0x03,0x00,0x00,0x00,//3(32位)
0x83,//添加eax,2//0x83=add,
0xc0,//ModR/M,具有立即8位值
0x02,//2(8位)
0xc3//ret
};
void*mem=VirtualAlloc(0,sizeof(代码),mem\u COMMIT,PAGE\u EXECUTE\u READWRITE);
memcpy(mem,code,sizeof(code));
德沃德·奥尔德;
VirtualProtect(mem、sizeof(mem)、执行页面、读取页面和旧页面);
int(*func)()=重新解释(mem);
printf(“编号为%d\n”,func());
VirtualFree(mem,0,mem_发布);
返回0;
}

是否有JIT汇编代码调用C++函数?< /P>


在这个项目之前,我用C++编写了一个字节代码解释器,但在与C语言中的等效测试程序进行比较时,我并不太满意。C#大约快25倍。所以我偶然发现了一种叫JIT的东西,可以让它更快。所以,我希望你们都能看到我把这个JIT项目带到了哪里。如果可能的话,可以让它处理GUI。

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

我不确定你调用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;
}
#包括
#包括
使用名称空间std;
__int64子系统(int64 a和int64 b)
{
返回a-b;
}
int main(int argc,字符**argv)
{
字符代码[]=
{
0x48,0x89,0xC8,//mov-rax,rcx
0xC3,//ret
0x48,0x83,0xEC,0x20,//子rsp,0x20
0xFF,0xD0,//调用rax
0x48,0x83,0xC4,0x20,//添加rsp,0x20
0xC3//ret
};
char*mem=static_cast(VirtualAlloc(0,sizeof(代码),mem_COMMIT,PAGE_EXECUTE_READWRITE));
移动内存(mem,code,sizeof(code));
auto setFunc=重新解释强制转换(mem);
自动调用函数=重新解释强制转换(mem+4);
setFunc(sub);
__int64 r=callFunc(0,1);

当然,这是可能的。大概是例子,也许是先看A。手工组装它会很有趣。注意函数调用不太可能是你的瓶颈。我通常在C/C++中编写一个示例程序,然后有编译器输出汇编代码,以获得程序集级名称和调用序列。在VisualStudio 2015中,PrtTF现在是包含文件的一部分,意味着它有效地被C/C++代码所内嵌。处理这个问题的一种方法是有一个项目包括一个用于打印的文件,一个用于其他项目的程序集文件。嗯,Irc,可以把CLAN转换成内存,然后用LLVM把它导入机器代码并运行它,因此通过学习LLVM源,你可能会得到答案。几年后……我也不清楚为什么你会被解释的语言速度困扰,只需在C++和汇编中写性能部件,J。通常情况下,它在大多数情况下都是不可能的,在任何适当的性能情况下都会表现不佳。对于非性能关键部件,25X也不重要。虽然这可能是一个很好的练习,可以让你知道C++是多么酷。))你如何防止C++在代码< > StFunc(子)之间污染<代码> RAX < /代码>?
\uuuu int64 r=callFunc(0,1);
?在我看来,这不是一个稳定的例子(尽管它可能在合理的低优化级别和足够的运气下工作)@Ped7g我的观点并不是说你可以按原样使用代码。如果你可以直接调用函数,你为什么要这样做。我的意思是说你可以用这种方式检索函数的地址,然后你可以用它做任何你想做的事,例如设置跳转表。@MegaStupidMonkeys这就是我真正感兴趣的。Tha谢谢你!