CLR/快速调用 : How are large value types passed internally to called functions?

标签 clr calling-convention

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


This book excerpt指出:

The CLR's jitted code uses the fastcall Windows calling convention. This permits the caller to supply the first two arguments (including this in the case of instance methods) in the machine's ECX and EDX registers.

最佳答案

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

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

关于CLR/快速调用 : How are large value types passed internally to called functions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8038397/

相关文章:

c# - 如何检测正在使用哪个 .NET 运行时(MS 与 Mono)?

.net - 我的代码将在哪个 CLR 中执行?

c - 函数参数如何在 C 中传递?

assembly - 如何确定是否应保留寄存器

assembly - ARM 调用约定是否允许函数不将 LR 存储到堆栈?

c中的调用约定

c# - 程序在启动后几乎立即崩溃

.net - .Core CLR 与 Mono CLR 有什么区别?那么微软为什么要维护运行时环境呢?

c++ - 在 Visual Studio 中的托管代码和非托管代码之间单步执行

c++ - 将 GNU 汇编程序编译到 Windows