如何将MSIL或CIL编写并编译成可执行文件?

问题描述 投票:0回答:1

我目前正在学习一点MSILCIL代码,我想编译一个用MSIL编写的基本Hello World。然而我遇到了一些麻烦。

起初我已经 阅读此文. 然后我把文章中的代码放在一个文件中,然后用 这个Stack Overflow答案 作为参考,以了解如何使用ilasm.exe和PEVerify.exe将该代码转化为可执行文件。

这就是我开始使用的方法。

.method static void main()
{
    .entrypoint
    .maxstack 1

    ldstr "Hello world!"
    call void [mscorlib]System.Console::WriteLine(string)

    ret
}

ilasm.exe可以制作可执行文件 但是当我运行PEVerify时,我得到了这样的输出。

PS C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools> .\PEVerify.exe /MD /IL C:\clr_code\hello_world_cil.exe

Microsoft (R) .NET Framework PE Verifier.  Version  4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

The module 'C:\clr_code\hello_world_cil.exe' was expected to contain an assembly manifest.
1 Error(s) Verifying C:\clr_code\hello_world_cil.exe

我搜索了这个错误,但只找到了关于使用反射生成动态代码的参考资料,这没有帮助。

然后我决定在Visual Studio中建立一个简单的hello world Console Application,并使用dotPeek来获取IL代码。然后我改变了hello world的信息,并尝试编译输出,这是我使用的代码。

.class private auto ansi beforefieldinit
  HelloMSILV472.Program
    extends [mscorlib]System.Object
{

  .method private hidebysig static void
    Main(
      string[] args
    ) cil managed
  {
    .entrypoint
    .maxstack 8

    // [6 9 - 6 10]
    IL_0000: nop

    // [7 13 - 7 53]
    IL_0001: ldstr        "Hello MSIL!"
    IL_0006: call         void [mscorlib]System.Console::WriteLine(string)
    IL_000b: nop

    // [8 13 - 8 35]
    IL_000c: call         int32 [mscorlib]System.Console::Read()
    IL_0011: pop

    // [9 9 - 9 10]
    IL_0012: ret

  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname instance void
    .ctor() cil managed
  {
    .maxstack 8

    IL_0000: ldarg.0      // this
    IL_0001: call         instance void [mscorlib]System.Object::.ctor()
    IL_0006: nop
    IL_0007: ret

  } // end of method Program::.ctor
} // end of class HelloMSILV472.Program

然而我得到了同样的错误。我还不知道.NET Framework IL和.NET Core IL之间是否有区别,目标框架是否会影响ilasm.exe处理代码的方式,所以我尝试了.NET Framework应用程序的输出IL和.NET Core应用程序的输出IL。然而我得到了同样的错误。

如何使用类似记事本++这样的东西,从头开始建立一个MSILCIL基本的hello world控制台应用程序,然后编译它,并有一个运行的可执行文件?

c# clr bytecode cil low-level
1个回答
1
投票

你的初始示例是好的--你只需要在顶部写上这一行,为你的代码声明一个汇编。

.assembly MyTestAssembly {}

此外,你应该引用你的代码所依赖的任何外部汇编。在这种情况下,因为它只是 mscorlib, ilasm 会在显示警告后找到它,所以不是强制性的,但为了调用其他自定义代码,它将是强制性的。

.assembly extern mscorlib {}

最终代码:

.assembly extern mscorlib {}
.assembly MyTestAssembly {}
.method static void main()
{
    .entrypoint
    .maxstack 1

    ldstr "Hello world!"
    call void [mscorlib]System.Console::WriteLine(string)

    ret
}
© www.soinside.com 2019 - 2024. All rights reserved.