简体   繁体   English

有关汇编中汇编的汇编入口点的信息在哪里?

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

I used to think that an assembly 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. 我曾经认为一个程序集只能有一个main()方法,直到我在哥本哈根的微软办公室的视频讲座中看到Jon Skeet的MiscUtil。

So, I wrote this little app that had two main() methods like so: 所以,我写了这个有两个main()方法的小应用程序,如下所示:

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. 我在Visual Studio中设置了StartUp对象并且它有效。 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? 我想知道是否将这种信息写入清单或PE图像的某些COFF标题中,这些标题在反汇编程序中无法看到但可以在十六进制编辑器中看到?

I just opened up one of my executables in the IL Disassembler. 我刚刚在IL反汇编程序中打开了一个可执行文件。 Notice the .entrypoint line for the Main method. 注意Main方法的.entrypoint行。

.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() vs非入口点方法 - 让我们说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>

您可以使用ildasm.exe进行检查

ildasm /ALL /TEXT program.exe

In the CLI header of the PE file at offset 20, there is the entrypoint token. 在偏移量为20的PE文件的CLI头中,有入口点令牌。 see section 25.3.3 of the ecma 335 specification. 请参阅ecma 335规范的第25.3.3节。

In IL you would place the .entrypoint directive into a method body. 在IL中,您可以将.entrypoint指令放入方法体中。 The method must be static, have no parameters or accept a an aray of strings. 该方法必须是静态的,没有参数或接受字符串的aray。 (varargs included). (包括varargs)。 you should see this in reflector if you change the language to IL. 如果将语言更改为IL,则应在反射器中看到此内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM