Можно ли с помощью MSVC прочитать конкретный 64 (или 32) битный регистр непосредственно в обычной функции C ++?
Например, можно ли как-то прочитать содержимое r10 через какие-либо встроенные функции или что-то подобное?
Для контекста:
Я реализую функцию с переменным числом (давайте назовем ее my_func), которая должна переадресовать ее вызов другой функции с переменным числом аргументов и добавить еще один аргумент по пути (ID, если хотите, подойдет любой числовой тип - a 16, 32 или 64-битное целое число, например, не имеет большого значения).
Мне нужно выполнить пересылку как можно меньше инструкций, поэтому я не могу обработать список переменных в исходной функции и просто переслать va_list или что-то подобное.
Итак, я реализовал my_func в сборке:
; This function needs to be as compact as possible
my_func PROC
; assume 123 is the ID to be passed along with the arguments that my_func is called with
mov r10, 123
jmp address_of_the_real_target_function
my_func
Я просто перехожу к целевой функции и передаю идентификатор в отдельный регистр - в данном случае R10.
ARG* the_real_target_function(ARG* arg0, ...)
{
auto id = ReadRegister();
// ... do stuff ...
}
Пока это работает хорошо - единственная неприятность в том, что мне понадобилась другая вспомогательная функция сборки для чтения R10 обратно в правильную функцию C ++,
ReadRegister PROC
mov rax, r10
ret
ReadRegister ENDP
, что немного раздражает, так как этот вызов не будет встроен.
Отсюда вопрос - есть ли способ прочитать этот регистр непосредственно в C ++?
(В противном случае я думал о том, чтобы, возможно, использовать регистры SSE, которые должны быть читаемы через встроенные функции - но любопытно, если есть способ сделать это только с 64- или 32-битными регистрами)
Спасибо
-
edit: я считаю, что не является дубликатом связанной темы. Перечисленные здесь решения относятся только к другим компиляторам или, в случае MSVC, только 32-разрядные (встроенная сборка не поддерживается в x64)
-
edit 2: Для получения дополнительной информации о том, почему я пытаюсь это сделать.
Этот индекс предназначен для добавления в Excel (который будет содержать плагины и, в основном, отображать их функции в Excel).
Чтобы зарегистрировать функцию в Excel, мне нужно привязать ее к определенной функции, экспортируемой моей DLL. Я не знаю заранее (= во время компиляции), сколько или какие функции плагина должны быть зарегистрированы и вызваны.
Поэтому мне нужно реализовать множество экспортируемых функций - тысячи. Достаточно всегда иметь регистрационные слоты для всех доступных плагинов.
Для того, чтобы контролировать общий размер DLL, мне нужно, чтобы зарегистрированные функции были очень тонкими и в идеале были бы способны работать с переменными аргументами (поскольку я не знаю, какую форму имеют функции плагина в время компиляции и из-за нехватки места я хочу избежать создания обратных вызовов для любого возможного количества аргументов)
И для еще большего удовольствия, он должен работать в x64 и x86 - хотя в последнем случае функция вызывается Excel через соглашение stdcall, поэтому обычные C ++ variadic args не будут работать. Но, по крайней мере, во время выполнения я могу узнать количество (и тип) аргументов, переданных функции, поэтому я должен иметь возможность обрабатывать стек самостоятельно.
Итак, моя идея состоит в том, чтобы иметь эти тонкие батутные функции, которые будут перенаправлять все аргументы, плюс их ID, в некоторый центральный обработчик (как указано выше в X64; и через стек в X86).
Затем обработчик приводит все в порядок - то есть создает некоторый стандартизированный итератор для аргументов, вызывает фактическую функцию плагина, зарегистрированную через этот идентификатор и т. Д.