"this" clr abi 文档中的指针

"this" pointer in the clr abi document

The "this" pointer

AMD64-only: Up to .NET Framework 4.5, the managed "this" pointer was treated just like the native "this" pointer (meaning it was the second argument when the call used a return buffer and was passed in RDX instead of RCX).

我在clr abi文档中找到了上面的语句,根据我的理解,它取决于.NET Framework 4.5,当调用使用return时,"this"指针是第二个参数buffer 并在 RDX 中传递;

所以我有两个问题:

  1. 缓冲区是什么意思?缓冲区指的是像 httpwebresponse 或其他任何东西的流缓冲区?

  2. 如果我们使用静态的class怎么样,我想在那种情况下,没有"this"指针存在并且上面的语句指定到实例对象,对吧?

很明显,微软一直在修补他们的 x64 abi。他们究竟做了什么,什么时候做了什么,但是非常不清楚,文档不完整,分散拍摄且日期不佳。我个人认为 Agner Fog 所做的 reverse-engineering work 是唯一真正可靠的信息来源。然而,他没有解决托管代码生成问题。

声称这在 4.5 中已更改是相当难以置信的。更有可能的是,这在 RyuJIT 中发生了变化,新的 x64 抖动取代了相当错误且无法维护的遗留 x64 抖动。最初作为 4.5.3 预览版发布,也许解释了 4.5 的声明,但后来增加到 4.6。 .NETCore 项目可能是这一变化的灵感来源,Microsoft x64 abi 与 Unix 代码生成器(GNU 和 LLVM)的差异相当令人痛苦。

但与 C++ 编译器代码生成器更改(根据 Agner Fog、gack 在 VS2015 更新中修改)不同,此更改不太可能被破坏。不匹配只能发生在 pinvoke 中,抖动从不支持 CallingConvention.ThisCall。幸运的是,您的问题很容易回答:

What's the meaning for the buffer?

这仅对 return 和 "aggregate type" 的方法有影响。换句话说,不适合 CPU 的值将不再注册。在 C# 中,这是一个 struct,进一步规定它必须是非平凡的(超过 2 个成员或非平凡的字段类型)。

方法调用者必须在其堆栈帧中为 return 值("buffer")分配 space,并传递指向该 space 的指针。该指针作为隐藏的额外参数传递给该方法。传统上是第一个参数,在隐藏的 this 参数之前。这使得 this 成为第二个参数,因此通过 RDX 寄存器而不是 RCX 寄存器传递。更改颠倒顺序,this 始终是第一个参数并通过 RCX 传递,return 值指针是第二个。被调用的方法将 return 值复制到 returns.

之前的缓冲区中

How about if we use the static class

仅与静态方法相关。然后没有额外的隐藏 this 参数,所以它被简单地省略了。实际上与之前的方式没有变化,隐藏的 return 值指针自动始终是第一个参数,因此通过 RCX 传递。

如果这对您很重要,那么一定要利用调试器的调试 > Windows > 反汇编 window。 运行 在一个小测试程序上,它很容易告诉你使用了哪些寄存器。