MSVC 有没有办法在普通的 C++ 函数中直接读取特定的 64(或 32)位寄存器?
例如,我可以通过任何内在函数等以某种方式读取 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
我只是跳转到目标函数,并将 ID 传递到一个单独的寄存器中 - 在本例中为 R10。
ARG* the_real_target_function(ARG* arg0, ...)
{
auto id = ReadRegister();
// ... do stuff ...
}
到目前为止效果很好——唯一的麻烦是我需要另一个汇编辅助函数来在正确的 C++ 函数中读回 R10,
ReadRegister PROC
mov rax, r10
ret
ReadRegister ENDP
这有点烦人,因为该调用不会被内联。
因此问题 - 有什么方法可以直接在 C++ 中读取这个寄存器吗?
(否则,我正在考虑可能使用 SSE 寄存器,它应该可以通过内部函数读取 - 但很好奇是否有一种方法可以仅使用 64 位或 32 位寄存器来做到这一点)
谢谢
--
编辑:我相信这不是链接主题的拷贝。那里列出的解决方案特定于其他编译器,或者在 os MSVC 的情况下,仅 32 位(x64 不支持内联汇编)
--
编辑 2:有关我尝试这样做的原因的更多背景信息。
这旨在成为一个 Excel 插件(基本上它将托管插件并将其功能公开给 Excel)。
为了在 Excel 中注册函数,我需要将它绑定(bind)到由我的 DLL 导出的特定函数。我事先不知道(= 在编译时)需要注册和调用多少个或哪些插件函数。 所以我需要实现大量的导出函数——数千个。足以始终为所有可用插件提供注册槽。
为了控制 DLL 的整体大小,我需要注册的函数非常精简,并且理想情况下还能够处理可变参数(因为我不知道插件函数的形状是什么)编译时;并且由于空间限制,我想避免为任何可能的论点创建回调)
为了获得更多乐趣,它需要在 x64 和 x86 中工作 - 尽管在后一种情况下,该函数由 Excel 通过 stdcall 约定调用,因此通常的 C++ 可变参数将不起作用。但是,至少在运行时我可以找出传递给函数的参数的数量(和类型),所以我应该能够自己处理堆栈。
归根结底,我的想法是拥有这些精简的蹦床函数,它们会将所有参数及其 ID 转发给某个中央处理程序(如上所示,在 X64 中;在 X86 中通过堆栈)。
处理程序然后将事情整理得井井有条——即为参数创建一些标准化的迭代器,调用通过该 ID 注册的实际插件函数等。
最佳答案
static thread_local
变量只需要很少的指令,所以它并不像您想要的那样 slim 。
然而,它将是完全便携的。
有一种不太便携但指令效率更高的方法。
注意 TEB 中的任意数据槽.
所以 __readfsdword(0x14)
/__writefsdword(0x14)
在 x86 和 __readgsqword(0x28)
/__writegsqword(0x28)
在 x64 上可以做到这一点。如果没有其他人将相同的额外空间用于其他目的。
关于c++ - MSVC : Reading a specific 64 or 32 bit register (e. g。 R10) 64 位代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54185053/