gpt4 book ai didi

c# - 评估堆栈的 .NET CIL 操作

转载 作者:太空狗 更新时间:2023-10-29 23:33:01 25 4
gpt4 key购买 nike

我有这个 CIL 代码序列,我通过使用 Mono.Cecil 注入(inject)了这些代码。但是,修改后的 .NET C# 应用程序将不会运行。

目标:手动从堆栈加载和弹出值以显示在 Console.WriteLine

 for (int i = 0; i < 3; i++)
{
int z = some value popped manually from stack;
Console.WriteLine(z);
}

这是我修改的简单 main() 程序:

.method private hidebysig static void Main(string[] args) cil managed
{

.entrypoint
.maxstack 5
.locals init (
[0] int32 num,
[1] int32 num2)
L_0000: ldc.i4.6 //manually push value 6 to stack
L_0001: ldc.i4.5 //manually push value 5 to stack
L_0002: ldc.i4.4 //manually push value 4 to stack
L_0003: ldc.i4.0 //push int i initial value 0 to stack
L_0004: stloc.0 //pop and store to int i variable to variable num
L_0005: br.s L_0013
L_0007: nop
L_0008: stloc.1 //pop the pushed values 6,5 and 4 to variable num2
L_0009: ldloc.1 //load value of num2 to stack
L_000a: call void [mscorlib]System.Console::WriteLine(int32) //pop value of num2 and print
L_000f: ldloc.0 //load previous value in variable num to stack
L_0010: ldc.i4.1 //load incremental value 1 to stack
L_0011: add //pop and add the top 2 values, result is pushed to stack
L_0012: stloc.0 //store the new result to variable num. (int i)
L_0013: ldloc.0 //push int i variable value to stack
L_0014: ldc.i4.3 //push value 3 to stack as number of times to loop
L_0015: blt.s L_0007 //branch less than (pop and cmp the top 2 values in stack)
L_0017: ret
}

但是,上面的代码无法运行。我尝试将 blt.s 更改为 cltbr_true.s 但它也不起作用。有谁知道是否有可能实现我的目标?谢谢。

编辑:根据 ECMA-335,III.1.7.5,可能存在向后分支约束。不确定是否是这种情况。

In particular, if that single-pass analysis arrives at an instruction, call it location X, that immediately follows an unconditional branch, and where X is not the target of an earlier branch instruction, then the state of the evaluation stack at X, clearly, cannot be derived from existing information. In this case, the CLI demands that the evaluation stack at X be empty.

最佳答案

您的 IL 代码看起来不错,但我认为 CLR 可能无法在方法完成后检查堆栈是否已损坏。当某些东西被压入堆栈时,CLR 会检查该值是否也从堆栈中弹出。

因此,如果您将 3 个值压入堆栈,CLR 可能无法检查您的循环是否运行了三次,因此 CLR 不知道方法返回时堆栈上是否仍有值。

关于c# - 评估堆栈的 .NET CIL 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12926476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com