.NET MSIL:命令如何检测操作数的大小?
.NET MSIL: How commands detect size of operands?
MSIL 中只有一个 add
命令可以添加两个参数(从堆栈弹出、添加、压入堆栈)。它如何知道它是否必须弹出 2 个字节或 4 个或 8 个字节?
在 java 不同的字节码(fadd、dadd、iadd 等)中,但他们如何在 .NET 中处理它?
来自 Common Language Infrastructure (CLI) Partition I: Concepts and Architecture,第 12.1 节:
... the CLI supports
only a subset of these types in its operations upon values stored on its evaluation stack—int32
, int64
, and
native int
. In addition, the CLI supports an internal data type to represent floating-point values on the internal
evaluation stack.
...
As described below, CIL instructions do not specify their operand types. Instead, the CLI keeps track of
operand types based on data flow and aided by a stack consistency requirement described below. For example,
the single add
instruction will add two integers or two floats from the stack.
讨论堆栈一致性的"below"参考第12.3.2.1节:
The evaluation stack is made up of slots that can hold any data type, including an unboxed instance of a value
type. The type state of the stack (the stack depth and types of each element on the stack) at any given point in a
program shall be identical for all possible control flow paths. For example, a program that loops an unknown
number of times and pushes a new element on the stack at each iteration would be prohibited.
也就是说,每当遇到add
指令时,它总是知道该点堆栈的"shape",因此可以构造正确的本机指令。无论如何,它只能使用一组有限的类型。
(CLI 的其他规范可以从 this page 中找到)
如果您编写 C# 测试程序并将其反编译为 MSIL,您可以看到在调用 add
之前,大小由 ldc
或 conv
指令设置。
Java 字节码被优化为由解释器执行,早期的 JVM 还没有 Hotspot。 .NET msil 从第一天开始就被设计成 总是,不需要针对不同操作数类型的特殊操作码。
抖动从堆栈状态知道操作数类型。将值压入堆栈的任何操作码也表明了类型。说一个 Opcodes.Ldarg_0,抖动从方法签名中知道类型。跟踪堆栈状态是您永远不想在解释器中做的事情,它会显着减慢代码执行速度,抖动只需要做一次。
MSIL 中只有一个 add
命令可以添加两个参数(从堆栈弹出、添加、压入堆栈)。它如何知道它是否必须弹出 2 个字节或 4 个或 8 个字节?
在 java 不同的字节码(fadd、dadd、iadd 等)中,但他们如何在 .NET 中处理它?
来自 Common Language Infrastructure (CLI) Partition I: Concepts and Architecture,第 12.1 节:
... the CLI supports only a subset of these types in its operations upon values stored on its evaluation stack—
int32
,int64
, andnative int
. In addition, the CLI supports an internal data type to represent floating-point values on the internal evaluation stack....
As described below, CIL instructions do not specify their operand types. Instead, the CLI keeps track of operand types based on data flow and aided by a stack consistency requirement described below. For example, the single
add
instruction will add two integers or two floats from the stack.
讨论堆栈一致性的"below"参考第12.3.2.1节:
The evaluation stack is made up of slots that can hold any data type, including an unboxed instance of a value type. The type state of the stack (the stack depth and types of each element on the stack) at any given point in a program shall be identical for all possible control flow paths. For example, a program that loops an unknown number of times and pushes a new element on the stack at each iteration would be prohibited.
也就是说,每当遇到add
指令时,它总是知道该点堆栈的"shape",因此可以构造正确的本机指令。无论如何,它只能使用一组有限的类型。
(CLI 的其他规范可以从 this page 中找到)
如果您编写 C# 测试程序并将其反编译为 MSIL,您可以看到在调用 add
之前,大小由 ldc
或 conv
指令设置。
Java 字节码被优化为由解释器执行,早期的 JVM 还没有 Hotspot。 .NET msil 从第一天开始就被设计成 总是,不需要针对不同操作数类型的特殊操作码。
抖动从堆栈状态知道操作数类型。将值压入堆栈的任何操作码也表明了类型。说一个 Opcodes.Ldarg_0,抖动从方法签名中知道类型。跟踪堆栈状态是您永远不想在解释器中做的事情,它会显着减慢代码执行速度,抖动只需要做一次。