MSIL是什么?
MSIL就是微软中间语言,也就是.NET程序的汇编语言。
今儿个没事儿,稍微研究了一下MSIL,就写了一个最简单的MSIL语言。
从代码结构布局上来看,MSIL更像是C++,编码指令却像是汇编一样,调用函数需要压栈推栈,代码的流程控制是靠跳转指令来完成的。
下面,我们来写一个最最简单的MSIL汇编程序,用CUI来显示我们的“Hello,宇宙!”
新建一个 Hello.il 文件,用记事本打开,然后加入下面的代码:
// 一个最最简单的MSIL汇编的控制台 “Hello 宇宙!”
// 定义导入的程序集
.assembly extern mscorlib //主程序集,控制台输出函数及基本数据类型都包含在内
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) //程序集元数据信息
.ver 2:0:0:0 //程序集版本;注意:它是非敏感的,如果没有符合版本,会调用高级版本;.NET 1.1 程序能运行在 2.0 环境中就是这个原理
}
// 设置本程序集信息
.assembly HelloUniverse { //我喜欢这种自由风格 ^_^
// 初始化程序集;该方法必须调用,否则无法执行
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.ver 1:2:3:4 //设置本程序集版本
}
// 设置模块信息
.module Hello.exe //模块名,可空
.subsystem 0x0003 //程序的运行模式,本例为控制台
/* 下面开始进入类型设置了 */
// 定义主类型
.class public Hello {
// 定义程序入口点,它是个静态函数,与.NET语言不同的是,你可以自己定义该方法的名称(任何奇怪的名字都可以)
.method assembly static int32 [] cls) {
.entrypoint //入口点声明
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 ) //设置方法属性
.maxstack 1 //设置最大堆栈
.locals init (int32 '整数',string '字符') //定义变量
// 开始IL汇编
ldstr "Hello,宇宙!!!" //将一个字符串压栈
call void [mscorlib]System.Console::WriteLine(string) //呼叫指定重载方法
call string [mscorlib]System.Console::ReadLine()
pop //弹出顶层堆栈
ldc.i4.0 //将四字节数值0压入堆栈
ret //退出并返回
}
}
新建一个 编译.bat ,用记事本打开,写入下面的代码:
@echo off
rem 调用ilasm开始汇编
%windir%\Microsoft.NET\Framework\v2.0.50727\ilasm /exe /out:ccx.exe "Hello.il"
pause
好了,一切都完成了,保存后执行批处理文件 编译.bat ,如果没有发生错误,则在当前目录中,会生成一个 ccx.exe 文件,执行这个文件,代我们向宇宙问好!