从JIT代码调用C ++(调用约定)

时间:2017-09-24 09:32:03

标签: c++ assembly 64-bit jit

我正在编写一个JIT编译器,它必须从编译的asm代码中调用c ++函数。

我目前只在Windows x64上工作,并实现了微软的调用约定。 (https://msdn.microsoft.com/en-us/library/ms235286.aspx

它有效,直到它没有。

如果被调用的函数很简单并且只调用简单的函数(使用类似C的子集),它似乎总能工作。 如果被调用函数调用其他函数,例如“std :: cout”,如果它是为Debug编译的,它可以工作,但不适用于发布。 如果被调用的函数调用某些VULKAN函数,它根本不起作用。

jit编译器生成的代码示例:

sub  %10 r64(4),  imm8(48)
mov  %1 r64(0),  %6 r64(1)
mov  %2 r64(2),  m64[%1]
mov  %3 r32(1),  imm32(5)
mov  ST: m64 +40,  %2 r64(2)
call  m64 <call PrintInt()>
mov  %2 r64(2),  ST: m64 +40
mov  m32[%2] +16,  %4 r32(0)
mov  %5 r32(0),  imm32(-2)
add  %10 r64(4),  imm8(48)
ret  

对象(使用x86-64转储到https://www.onlinedisassembler.com/odaweb/):

48 83 EC 30 48 89 C8 48 8B 10 B9 05 00 00 00 48 89 54 24 28 FF 15 D6 FF FF FF 48 8B 54 24 28 89 42 10 B8 FE FF FF FF 48 83 C4 30 C3

调用的函数就像(发布时失败)一样简单:

int PrintInt(int nr) {
std::cout << nr << std::endl;   // error
return nr;
}

错误是: “test.exe中的0x000007FEE3693D39(msvcp140.dll)抛出异常:0xC0000005:访问冲突读取位置0x0000000000000000。”

知道我缺少什么吗?

使用我的评论编辑反汇编

sub rsp, 0x30               // subtract 48 bytes from stack pointer to get 6 slots of space
mov rax, rcx                // rcx is a pointer parameter
mov rdx, QWORD PTR [rax]    // load pointer from [rax]
mov ecx, 0x5                // imm 5 into ecx for function call
mov QWORD PTR [rsp+0x28], rdx   // save rdx for after function call on the stack
call QWORD PTR [..]         // function call
mov rdx, QWORD PTR [rsp+0x28]   // get rdx back from stack
mov DWORD PTR [rdx+0x10], eax   // save result
mov eax, 0xfffffffe             // -2 in eax (return value)
add rsp, 0x30               // restore stack ptr (free)
ret

STACK:

.... start
[XXX] used to save rdx
[   ] unused
[ s ]
[ s ]
[ s ]
[ s ]  shadow space
.... call

我预留了6个插槽(8个字节),因此我在呼叫路由时得到了16个字节。

感谢您的帮助。

0 个答案:

没有答案