Сборка — вызов C ++ из кода JIT (соглашение о вызовах)

Я программирую JIT-компилятор, который должен вызывать функции c ++ из скомпилированного кода asm.

Я до сих пор работаю на Windows x64 и реализовал соглашение о вызовах от Microsoft. (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

Объект (сброс в https://www.onlinedisassembler.com/odaweb/ с x86-64):

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;
}

Ошибка:
«Исключение, выданное по адресу 0x000007FEE3693D39 (msvcp140.dll) в test.exe: 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

СТЕК:

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

Я резервирую 6 слотов (8 байт), поэтому получаю 16 байт при выравнивании вызовов.

Спасибо за любую помощь.

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]