【问题标题】:C#/CIL: type of native intC#/CIL:本机 int 类型
【发布时间】:2019-02-15 14:47:52
【问题描述】:

我正在编写一些工具来帮助验证在运行时发出的 IL。此验证的一部分涉及在发出操作码时维护Stack<Type>,以便将来使用这些堆栈元素的操作码可以被验证为使用正确的类型。但是,我对如何处理 ldind.i 操作码感到困惑。

Microsoft 文档指出:

ldind.i 指令间接从 指定的地址(本机 int、& 或 * 类型)作为 本机 int。

在 C# 中,未定义原生 int,我对哪种类型最准确地表示此数据感到困惑。如何确定它的大小,以及应该使用哪种 C# 类型来表示它?我担心它会因系统硬件而异。

【问题讨论】:

  • a:没有,b:是的,它可能取决于硬件运行时(x86/x64等);顺便说一句 - 您可能会发现 Sigil(也称为 here)是您正在寻找的一切,但已经构建和测试
  • 它是 C# 中的 IntPtr。关于它的“原生”是它的大小根据进程位数而变化,32 位模式下为 4 个字节,64 位模式下为 8 个字节。使其能够存储指针。从 C# 程序获取 ldind.i 需要 fixed 关键字通过指针访问 IntPtr[] 数组。这是不可验证的不安全代码,没有边界检查。
  • 那么,澄清一下,ldind.i 本质上是取消引用指向本机指针的本机指针?例如。堆栈上的地址是IntPtr**?
  • 不,IntPtr*。 IntPtr foo[] = 新的 IntPtr[1];固定 (IntPtr* p = &foo[0]) { var value = *p; }
  • 更简单:IntPtr* p = null; var v = *p;

标签: c# cil


【解决方案1】:

在我看来,你最好看看 VES 是如何定义的,并使用专用枚举来对堆栈上的类型而不是 C# 可见类型进行建模。否则,当我们谈到浮点类型时,您会大吃一惊。

来自 MS Partition I.pdf1,第 12.1 节:

CLI 模型使用评估堆栈 [...] 但是,CLI 在其对存储在其评估堆栈上的值的操作中仅支持这些类型的一个子集 —int32int64native int。此外,CLI 支持 内部数据类型来表示内部评估堆栈上的浮点值。内部数据类型的大小取决于实现。

因此,您应该跟踪这些以及参考之类的内容,我建议您使用 its 术语使用 VES 堆栈的显式模型来做到这一点。


1ECMA C# and Common Language Infrastructure Standards

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多