MSVC:以64位代码读取特定的64位或32位寄存器(例如R10)?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MSVC:以64位代码读取特定的64位或32位寄存器(例如R10)?相关的知识,希望对你有一定的参考价值。

有没有办法让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位寄存器来实现这一点)

谢谢

--

编辑:我认为这不是链接主题的重复。其中列出的解决方案是针对其他编译器的,或者是os MSVC,仅限32位(x64不支持内联汇编)

--

编辑2:有关我为什么要这样做的更多背景信息。

这是一个Excel Add In(它将托管插件并将其功能暴露给Excel,基本上)。

为了在Excel中注册一个函数,我需要将它绑定到我的DLL导出的特定函数。我事先并不知道(=在编译时)有多少,或者需要注册和调用哪些插件函数。所以我需要实现大量的导出函数 - 数千个。足以为所有插件提供注册插槽。

为了控制DLL的整体大小,我需要注册的函数非常纤薄,理想情况下还能够处理可变参数(因为我不知道插件函数在编译时的形状是什么;由于空间限制,我想避免为任何可能的参数创建回调)

而且为了更多的乐趣,它需要在x64和x86中工作 - 尽管在后一种情况下,该函数由Excel通过stdcall约定调用,因此通常的C ++可变参数args将不起作用。但是,至少在运行时我可以找到传递给函数的args的数量(和类型),所以我应该能够自己处理堆栈。

所以底线,我的想法是拥有这些纤细的trampoline函数,它们将所有参数以及它们的ID转发给某个中央处理程序(如上面的X64;以及通过X86中的堆栈)。

然后处理程序将事情按顺序排列 - 即为参数创建一些标准化迭代器,调用通过该ID注册的实际插件函数等。

答案

static thread_local变量只需要很少的指令,所以它并不像你想要的那么纤细。然而,它将是完全便携的。

便携性较低但指导效率更高。注意TEB中的任意数据槽。因此x86上的__readfsdword(0x14) / __writefsdword(0x14)和x64上的__readgsqword(0x28) / __writegsqword(0x28)可能会做到这一点。如果,没有其他人使用相同的额外空间用于其他目的。

以上是关于MSVC:以64位代码读取特定的64位或32位寄存器(例如R10)?的主要内容,如果未能解决你的问题,请参考以下文章

检测 32 位或 64 位 Windows

安装的jvm是64位或32位[重复]

汇编语言中的CPU的16位,32位和当今操作系统所指的32位,64位概念有点模湖,请大侠们赐教.

如何根据浏览器在同一页面上嵌入 32 位或 64 位 ActiveX 控件?

在 64 位 Windows 上安装 32 位或 64 位应用程序有啥区别?

检测32位或64位Windows