Я написал JITting VM для Brainfuck. Для этого требуется создание области записи с возможностью записи и записи (то есть, char*
, но не созданной с помощью malloc
или new
), которая заполняется машинным кодом операции (x64 в моем случае), а затем вызывается после преобразования char*
в указатель функции. Эта вновь созданная функция имеет параметры. А именно, указатель на память и некоторые другие внутренние вещи.Как узнать, какие параметры функции регистров будут отображаться?
Он работает, но предполагает определенное отображение регистров. Это сопоставление изменилось, когда-то, потому что я изменил код вокруг вызова в char*
, и компилятор решил, что он будет работать лучше с другими регистрами. Поэтому мне пришлось изменить схему генерации кода.
Я боюсь, что смогу сделать что-то, что заставит компилятор изменить его или, что еще хуже, использовать стек, который я не знаю, как вытащить параметры из (пока).
Так что мне нужно:
- способ, чтобы сообщить компилятору о том, что регистры поставить параметры (`регистр ... ассемблер («r0»), как описано here, не работает с параметрами)
- еще один способ узнать, как регистрируются параметры. Это будет сложнее, но это все еще возможно.
- еще способ узнать, если и в каком порядке были переданы параметры в стек
Я использую GCC 4.8.2.
Какой компилятор вы используете? Если вы используете 'gcc', вы можете написать встроенную ассемблерную оболочку, которая вызывает jit-сгенерированный код. Затем вы можете использовать свои собственные соглашения о вызовах. – swegi
Если вы обнаружили параметры в разных регистрах, то я сильно подозреваю, что вы не искали нужного места для начала. Скорее, я подозреваю, что вы * произошли *, чтобы найти нужное вам значение в регистре, но вызывающий абонент просто использовал этот регистр как временное местоположение, прежде чем копировать параметр в нужное место. Вы полагались на остатки. Вызывающая конвенция должна быть хорошо установлена; он не изменится с одной сборки на другую, если вы явно не используете директиву, которая определяет соглашение о вызове. –
@RobKennedy, я смотрел на разборку, а не на значения в регистрах. Я не могу вспомнить слишком хорошо сейчас, что я тогда сделал, но оказалось, что у меня есть один дополнительный параметр, используя% rdi и перестановку остальных в% rsi ->% r9 вместо% rdi ->% r8, м, используя теперь. Тогда я плохой. – Gabriel