c++ - MSVC : Reading a specific 64 or 32 bit register (e. g。 R10) 64 位代码?

标签 c++ visual-studio assembly

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/

相关文章:

gcc - 汇编器模板、asmSymbolicName 和 "error: expected string-literal"

windows - 二进制文件(PE/COFF 和 ELF)格式和术语的说明

assembly - 这些变量之间的依赖关系是什么?

c++ - 高级文件和字符串操作

c++ - 如何通过套接字发送PDF文件?

windows - 在哪里可以下载 Visual Studio 2012 RC 和 Windows 8 Customer Preview?

html - Bootstrap 按钮 - 无手形光标

c++ - 什么是 C++ 内联类?

c++ - 将命令行的输出逐行读取到 C++ 中的字符串 vector 中

c++ - Qt中的多级继承