Why can't I load 2 rows onto the stack like this: (IL)

.assembly Hello {} .method public static void Main() cil managed { .entrypoint .maxstack 8 ldstr "Hello, world!" ldstr "Hello, world!2" call void [mscorlib]System.Console::WriteLine(string) ret } 
  • I assumed that it should be so, but the compiler gives an error even without calling the function. - Andrey
  • Oh, incorrectly explained. The compilation is successful, with the launch of the problem: pp.vk.me/c604629/v604629034/276d4/v6F2Zb2_S0g.jpg - Andrei
  • That is, the problem is that ret cannot return a stack with 2 values? - Andrey
  • Thank you very much for such a meaningful answer) - Andrew
  • @Mike would have already issued a full response, the information in your comments is enough for this - rdorn

1 answer 1

ldstr loads the address of the string ldstr stack. According to the calling convention used in IL, clean up the stack, i.e. deleting function arguments from it is performed by the called function. WriteLine expects to receive one parameter and removes one value from the stack. You put 2 values ​​on the stack, so at the time of the ret execution, you have one extra thing left on the stack.

At the time of the call of any function on the top of the stack is the return address where ret should return control when the function ends. At the time of execution, ret takes the return address from the top of the stack and navigates to that address. If at the moment of execution of ret there is an extra value in the stack (which you put there and no one took it from there) then ret will not know where to return and the program will crash.