我正在将代码从 C# 转换为 IL(CIL/MSIL 等)。我陷入了条件限制,因为我希望能够存储到下一个可用的空闲位置。示例:
var x = 0;
if(x > 20)
x = 1;
Console.WriteLine(x);
如果我将其转换为我认为正确的 IL,我会得到:
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: ldc.i4.s 14
IL_0006: cgt
IL_0008: ldc.i4.0
IL_0009: ceq
IL_000B: stloc.1
IL_000C: ldloc.1
IL_000D: brtrue.s IL_0011
IL_000F: ldc.i4.1
IL_0010: stloc.0
IL_0011: ldloc.0
IL_0012: call System.Console.WriteLine
我相信这是正确的 IL,但我的示例非常静态。如果你在 IL 代码中看到,它将 ceq 的结果存储到 loc.1
这就是我的问题——编译器发现 loc.0 已被占用(变量“x”)并使用下一个空闲位置,即 1。我的目标是在给定方法可以的情况下动态地执行此操作条件之前有 N 个变量。
最后,这是我的问题: 我如何从 C# 发出一个操作码来表示“STLoc.nextAvailable”及其等效负载?
最佳答案
STLoc
和 ldloc
仅适用于常量索引。但这并不是一件坏事 - 这意味着如果您发出了其他代码,您已经拥有下一个可用索引,或者如果您以某种方式在其他地方获取了代码,您所要做的就是取所有本地索引的最大值并添加一个(或者从方法头中读取局部变量的数量(如果有的话)。
或者您可以跳过本地并直接使用cgt
的结果(使用brfalse
),或者使用ble
指令。那么这个问题根本就不会出现。
关于c# - CIL 中的条件——如何获取下一个空闲位置来存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11111087/