MSVC:在64位代码中读取特定的64位或32位寄存器(例如R10)
MSVC: Reading a specific 64 or 32 bit register (e.g. R10) in 64 bit code?
MSVC是否有任何方法可以在普通C++函数中直接读取特定的64(或32)位寄存器?
例如,我可以通过任何内部函数或类似函数以某种方式读取r10的内容吗?
对于上下文:
我正在实现一个变参数函数(让我们称之为my_func),它需要将调用转发到另一个变函数,并在此过程中再添加一个参数(如果愿意,可以使用ID,任何数字类型都可以-例如,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位寄存器)
感谢
--
edit:我相信这不是链接主题的重复。中列出的解决方案特定于其他编译器,或者在操作系统MSVC的情况下,仅限32位(x64上不支持内联程序集)
--
编辑2:关于我为什么要这么做的更多上下文。
这被认为是一个Excel插件(基本上,它将托管插件并向Excel公开其功能)。
为了在Excel中注册函数,我需要将其绑定到DLL导出的特定函数。我事先不知道需要注册和调用多少插件函数。因此,我需要实现大量导出的函数——数千个。足够总是为所有可用的插件提供注册槽。
为了控制DLL的整体大小,我需要注册的函数非常小,并且理想情况下还能够处理可变参数(因为我不知道编译时插件函数的形状;由于空间限制,我想避免为任何可能的任意参数创建回调)
更有趣的是,它需要在x64和x86中工作——尽管在后一种情况下,该函数是由Excel通过stdcall约定调用的,所以通常的C++可变参数不起作用。但是,至少在运行时,我可以找到传递给函数的参数的数量(和类型),所以我应该能够自己处理堆栈。
所以,最重要的是,我的想法是拥有这些纤细的蹦床函数,它将把所有参数及其ID转发给某个中央处理器(如上面X64中所述;以及X86中的堆栈)。
然后,处理程序将事情稍微整理一下,即为参数创建一些标准化的迭代器,调用通过该ID等注册的实际插件函数。
static thread_local
变量需要很少的指令,所以它并不像您想要的那么瘦。然而,它将是完全可移植的。
有一种便携性较低但教学效率较高的方法。注意TEB中的任意数据槽。因此,x86上的__readfsdword(0x14)
/__writefsdword(0x14)
和x64上的__readgsqword(0x28)
/__writegsqword(0x28)
可以做到这一点。如果没有其他人将同样的额外空间用于其他目的。
- 本质:使用__128寄存器
- 将寄存器设计成可由C和C++访问的外设的最佳实践
- 将应用程序从32位移植到64位时出现问题
- 64位机器上的C++内存对齐
- 在模拟器中使用并集来模拟CPU寄存器有多合适
- qmake:检测目标位宽(32 位或 64 位)
- 使用 AVX 对两个 zmm(512 位)寄存器进行异或运算
- 使用移位寄存器的按位运算
- 在x86_64模式下,64 位数字不适合寄存器整数
- X86-64上的C :何时通过结构/类在寄存器中返回
- MSVC:在64位代码中读取特定的64位或32位寄存器(例如R10)
- 有4位,如何为AVX寄存器产生口罩
- SSE 64 位寄存器
- 超大枚举器(> 64 位类型)
- 在Visual Studio上为.net构建64位的QUICKFIX.. NET c++ DLL包装器)
- 为64位dll创建32位包装器.这可能吗?
- 通过自定义的 printf 功能跨平台打印 64 位交互器
- 如何在64位(而不是任何80位寄存器)中强制所有双精度
- 为什么gcc/clang使用两个128位的xmm寄存器来传递单个值
- 64位的DirectShow基类的链接器问题