CLR/Fastcall:大值类型如何在内部传递给被调用函数?

Dan*_*ker 4 clr calling-convention

只是出于好奇:值类型通常是复制的,并且 JIT 编译器在调用方法时似乎使用 Microsoft 的 Fastcall 调用约定。这会将前几个参数放入寄存器中,以便快速访问。但是大值类型(即大于寄存器的大小或堆栈的宽度)如何传递给被调用的函数?


这本书的摘录指出:

CLR 的即时代码使用 fastcall Windows 调用约定。这允许调用者在机器的 ECX 和 EDX 寄存器中提供前两个参数(包括实例方法的情况)。

Han*_*ant 6

它是__clrcall,确实类似于__fastcall。x86 抖动使用两个寄存器(ecx、edx)。x64 抖动的四个寄存器(ecx、edx、r8、r9),与本机 x64 调用约定相同。像 Decimal 和大型结构这样的大值类型是通过在调用者堆栈上保留空间、将值复制到其中并传递指向此副本的指针来传递的。被调用者再次将其复制到自己的堆栈帧中。

这是昂贵的,这就是为什么 Microsoft 建议结构体不应大于 16 字节。有意通过 ref 传递结构以避免复制是一种解决方法,通常在 C 和 C++ 中这样做。以额外的指针取消引用为代价。