请看C#代码:
namespace ILTest { public sealed class Program { public static void Main(string[] args) { int result = Program.Add(1, 2); } public static int Add(int a, int b) { int c = 0; return a + b; } } }
IL代码:
.method public hidebysig static void Main ( string[] args ) cil managed { // Method begins at RVA 0x2050 // Code size 10 (0xa) .maxstack 2 .entrypoint .locals init ( [0] int32 result ) IL_0000: nop IL_0001: ldc.i4.1 IL_0002: ldc.i4.2 IL_0003: call int32 ILTest.Program::Add(int32, int32) IL_0008: stloc.0 IL_0009: ret } // end of method Program::Main .method public hidebysig static int32 Add ( int32 a, int32 b ) cil managed { // Method begins at RVA 0x2068 // Code size 11 (0xb) .maxstack 2 .locals init ( [0] int32 c, [1] int32 CS$1$0000 ) IL_0000: nop IL_0001: ldc.i4.0 IL_0002: stloc.0 IL_0003: ldarg.0 IL_0004: ldarg.1 IL_0005: add IL_0006: stloc.1 IL_0007: br.s IL_0009 IL_0009: ldloc.1 IL_000a: ret } // end of method Program::Add
可以看到,C#编译器自动生成了一个用来存放返回值的变量CS$1$0000,在方法执行到最后,evolustion stock的栈顶应该是返回值,再看Main方法,IL_0008行代码把数据从栈顶拿出来赋值给了变量result。是不是可以说:
我看到有人说“每一次方法调用都会产生一个Evaluation Stack”,这种说是错误的吧,如果这种说法是正确的,那么方法的返回值到底放在了哪里了?谢谢。
evolustion stock 应该是每个方法调用会产生一个。
ret 后会把返回值放到调用者的 evolustion stock 里
谢谢
请问有什么资料里提到这个问题吗?我没有查到资料,我只看代码觉得确实是所有方法公用一个Stock。
你说的对。ret指令会将返回值推到调用方栈上