我目前正在学习一点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控制台应用程序,然后编译它,并有一个运行的可执行文件?
你的初始示例是好的--你只需要在顶部写上这一行,为你的代码声明一个汇编。
.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
}