Итак, я написал небольшую библиотеку, которая позволяет мне выполнять необработанный байт-код, как в инструкциях по сборке, в C ++.
Я подумал написать с ним компилятор brainfuck-to-x64. Все работало, пока мне не пришлось реализовать инструкцию .
brainfuck, которая печатает символ на стандартный вывод.
Я знаю, что мне нужно передать (только) аргумент через rcx
(согласно cdecl). Но я не знаю, как настроить стек или очистить после вызова функции. Мой код ASM выглядит следующим образом:
push rbp ; This is the only thing I tried doing as an epilog
mov rcx, QWORD PTR [rbx+rax*4] ; rbx contains the address of an array (32-bit elements), and rax contains the index, the character byte is saved in that address
push rax ; Retrieve rax after it gets clobbered by putchar
push rcx ; Push rcx to use it as an argument
call r10 ; r10 contains the address of putchar
pop rcx ; Restore all clobbered registers
pop rax
pop rbp
Этот фрагмент кода работает, персонаж попадает в стандартный вывод, но после этого я просто получаю "Access violation executing location 0x0000000000000000.
"
Что я отсутствует? Похоже, что putchar не возвращается корректно из-за повреждения rsp
или из-за чего-то
Кстати, я получил адрес putchar следующим образом:
#include <cstdio>
uint_least64_t putchar_addr = (uint_least64_t)&std::putchar;
Мне нужно получить указатель в виде целого числа, поэтому я могу добавить его в буфер кода в виде байт-кода позже.