开发者

Where is the information about the entry point of an assembly written in the assembly?

开发者 https://www.devze.com 2023-01-08 18:04 出处:网络
I used to think that an as开发者_如何学JAVAsembly could have only one main() method until I saw Jon Skeet\'s MiscUtil in a video lecture he delivered at the Microsoft office in Copenhagen.

I used to think that an as开发者_如何学JAVAsembly could have only one main() method until I saw Jon Skeet's MiscUtil in a video lecture he delivered at the Microsoft office in Copenhagen.

So, I wrote this little app that had two main() methods like so:

namespace ManyMains
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
            Console.ReadKey();
        }
    }

    class YetAnotherProgram
    {
        static void Main()
        {
            Console.WriteLine("Yet another program.");
            Console.ReadKey();
        }
    }
}

I set the StartUp object in Visual Studio and it worked. Okay, no cause for distress. Then, I wanted to see where exactly this information is stored in the assembly, so I opened the compiled binary in reflector and saw absolutely no metadata to that effect.

I'm wondering if that sort of information is written into the manifest or some COFF header of the PE image that can't be seen in a disassembler but could be seen in a hex editor?


I just opened up one of my executables in the IL Disassembler. Notice the .entrypoint line for the Main method.

.method public hidebysig static void  Main() cil managed
{
  .entrypoint
  .custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) 
  .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       22 (0x16)
  .maxstack  1
  .locals init ([0] class AuctionSniper.Main.App app)
  IL_0000:  nop
  ... <snipped>

vs a non-entry point method - Lets say InitializeComponent()

.method public hidebysig instance void  InitializeComponent() cil managed
{
  .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) 
  // Code size       20 (0x14)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  ... <snipped>


You can check that using ildasm.exe

ildasm /ALL /TEXT program.exe


In the CLI header of the PE file at offset 20, there is the entrypoint token. see section 25.3.3 of the ecma 335 specification.

In IL you would place the .entrypoint directive into a method body. The method must be static, have no parameters or accept a an aray of strings. (varargs included). you should see this in reflector if you change the language to IL.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号