I recently played with MSIL and compiled it with ilasm when I noticed that this method requires the ret command to return from the end of the method; For example, I should write code like this:
.method static void Main() { .entrypoint ldstr "Hello World!" call void [mscorlib]System.Console::WriteLine(string) ret
However, if I omit ret, the code still works and displays "Hello World!". perfectly. At first, I thought it might be specific to the entrypoint method, but ilasm happily compiles this code without warnings and errors:
.assembly Program{} .assembly extern mscorlib{} .method static void Main() { .entrypoint ldstr "Hello World!" call void [mscorlib]System.Console::WriteLine(string) ldstr "Foo returned: {0}!" call int32 Foo() box int32 call void [mscorlib]System.Console::WriteLine(string, object) } .method static int32 Foo() { ldstr "Hello from Foo!" call void [mscorlib]System.Console::WriteLine(string) ldstr "GoodBye!" call void [mscorlib]System.Console::WriteLine(string) ldc.i4 42 }
Note that neither Main () nor Foo () have return statements. Foo () even has a return value! When this code compiles and runs, I get the following output:
Hello World! Hello from Foo! Goodbye! Foo is back: 42!
The program also exits normally. Then I thought that perhaps ilasm automatically inserts ret statements, but after viewing the program using ildasm, the methods were identical with the code above ie without returning.
Curiously, when I tried to decompile the method using DotPeek, it refused to replace both bodies of the method with // ISSUE: unable to decompile the method.
If I add ret statements and recompile DotPeek, both methods can be decompiled without problems.
Can someone explain what is going on here?
source share