Can someone explain these few lines of MSIL?

Can someone explain these few lines of MSIL? Why does this move the value from the evaluation stack to a local variable, only to immediately return it and return it?

The following MSIL code loads a single argument (string), calls a method that returns bool, and then returns that bool value. I don’t understand why it calls stloc.0 to store the return value of the method in a local variable, and then performs explicit unconditional control of passing to the next next marked line (it seems unnecessary), only to move the value directly to the evaluation stack before returning it.

.maxstack 1
.locals init ([0] bool CS$1$0000)
L_0000: nop
L_0001: ldarg.0
L_0002: call bool FuncNameNotImporant::MethodNameNotImporant(string)
L_0007: stloc.0 
L_0008: br.s L_000a
L_000a: ldloc.0 
L_000b: ret 

My best guess is why this is done in order to do some type checking to ensure that the value in the evaluation stack is actually a boolean before returning it. But I do not know about an explicit jump to the next line; I mean, will he go there? The C # source code for a method is just one line that returns the result of the method.

+5
source share
2 answers

If you open this function in the debugger, the code is compiled in debug mode:

bool foo(string arg)
{
    return bar(arg);
}

There are three breakpoints you can set:

  • In the opening bracket of the function.
  • In the line "return".
  • In the closing bracket of the function.

" ". no-op. ​​ , no-op.

" ". , IL, .

return retVal;

$retTmp = retVal;
goto exit;

:

exit:
return $ret;

, , . - :

GenerateProlog();
foreach (var statement in statements)
{
    Generate(statement);
}
GenerateEpilog();

:

return foo(arg);

:

; //this is a no-op
bool retTemp = false;
retTemp = foo(arg);
goto exit;
exit:
return retTemp;

"" ", , . . , , , . , .

. , , :

return bar(arg);

.

, , , # . , JIT. , , # JIT- ( , , , ). . " " ( JIT ), , , .

+7

? :

.method private hidebysig static bool Test1(string arg) cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: call bool FuncNameNotImportant::MethodNameNotImportant(string)
    L_0006: ret 
}

, , , .

+4

All Articles