前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >详解.net中IL语言

详解.net中IL语言

作者头像
付威
发布2018-12-05 15:58:03
1.3K0
发布2018-12-05 15:58:03
举报

什么是IL语言

中间语言,又称(IL语言)。充当Clr与.net 平台的中间语言,比如用C#编写程序,编译器首先是把C#代码转译成IL语言,最终由Clr解释执行,下面我们学习下IL语言。

如何读懂IL语言

  • 写一个helloworld的.net 程序,编译运行完成。
      static void Main(string[] args)
      {
          Console.WriteLine("hello world");
      }
  • 使用ildasm.exe(C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools)反编译代码,得到IL代码如下:
     .method private hidebysig static void  Main(string[] args) cil managed
      {
        .entrypoint
        // 代码大小       13 (0xd)
        .maxstack  8
        IL_0000:  nop
        IL_0001:  ldstr      "hello world"
        IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)
        IL_000b:  nop
        IL_000c:  ret
      } // end of method Program::Main
  • 查找对应的指令表,来确定对应的含义

指令名称

说明

Ldstr

推送对元数据中存储的字符串的新对象引用。

Nop

如果修补操作码,则填充空间。尽管可能消耗处理周期,但未执行任何有意义的操作。

Call

调用由传递的方法说明符指示的方法。

Ret

从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上。

  • 其它几个名词的的解释 hidebysig: 与之对就的是hidebyname,这个是确定使用方法的签名还是使用方法的名称来确定调用哪个方法.
  • 整个的IL语言解释
   .method private hidebysig static void  Main(string[] args) cil managed
      {
        .entrypoint //代码入口 
        // 代码大小       13 (0xd)
        .maxstack  8  //整个程序的堆栈大小
        IL_0000:  nop  //无实在意义
        IL_0001:  ldstr      "hello world"  //定义字符
        IL_0006:  call       void [mscorlib]System.Console::WriteLine(string)   //调用WriteLine变量
        IL_000b:  nop
        IL_000c:  ret  //返回
      } // end of method Program::Main

更复杂的Demo

  • 添加编写如下C#代码
 class Program
  {
      static void Main(string[] args)
      {
          var a = 0;
          var b = 1;
          var c = Add(a, b);
          Console.WriteLine(c.ToString());
      }

      public static int Add(int x,int y)
      {
          return x + y;
      }
  }
  • 生成相关的IL代码及解释
	.method private hidebysig static void  Main(string[] args) cil managed
	{
	.entrypoint
	// 代码大小       27 (0x1b)
	.maxstack  2
	.locals init ([0] int32 a,
			[1] int32 b,
			[2] int32 c) //定义3个变量
	IL_0000:  nop
	IL_0001:  ldc.i4.0 //将整数值 0 作为 int32 推送到计算堆栈上。
	IL_0002:  stloc.0  //从计算堆栈的顶部弹出当前值并将其存储到索引 0 处的局部变量列表中。
	IL_0003:  ldc.i4.1 //将整数值 1 作为 int32 推送到计算堆栈上。
	IL_0004:  stloc.1  //从计算堆栈的顶部弹出当前值并将其存储到索引 1 处的局部变量列表中。
	IL_0005:  ldloc.0  //将索引 0 处的局部变量加载到计算堆栈上,这里指a。
	IL_0006:  ldloc.1  //将索引 1 处的局部变量加载到计算堆栈上,这里指b。
	IL_0007:  call       int32 ILTest.Program::Add(int32,
													int32)  //调用Add方法
	IL_000c:  stloc.2 //将索引 2 处的局部变量加载到计算堆栈上,这里指c。 
	IL_000d:  ldloca.s   c  //将位于特定索引处的局部变量的地址加载到计算堆栈上(短格式)。
	IL_000f:  call       instance string [mscorlib]System.Int32::ToString() 
	IL_0014:  call       void [mscorlib]System.Console::WriteLine(string)
	IL_0019:  nop
	IL_001a:  ret
	} // end of method Program::Main

Add方法:

	.method public hidebysig static int32  Add(int32 x,int32 y) cil managed
	{
	// 代码大小       9 (0x9)
	.maxstack  2
	.locals init ([0] int32 V_0) //创建一个V_0的局部变量
	IL_0000:  nop
	IL_0001:  ldarg.0 //将索引为 0 的参数加载到计算堆栈上。
	IL_0002:  ldarg.1 //将索引为 1 的参数加载到计算堆栈上。
	IL_0003:  add     //将两个值相加并将结果推送到计算堆栈上。
	IL_0004:  stloc.0
	IL_0005:  br.s       IL_0007   //无条件地将控制转移到目标指令(短格式)
	IL_0007:  ldloc.0    //将索引 0 处的局部变量加载到计算堆栈上。
	IL_0008:  ret
	} // end of method Program::Add

(本文完)

作者:老付 如果觉得对您有帮助,可以下方的订阅,或者选择右侧捐赠作者,如果有问题,请在捐赠后咨询,谢谢合作 如有任何知识产权、版权问题或理论错误,还请指正。 自由转载-非商用-非衍生-保持署名,请遵循:创意共享3.0许可证 交流请加群113249828: 点击加群 或发我邮件 laofu_online@163.com

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-10-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是IL语言
  • 如何读懂IL语言
  • 更复杂的Demo
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档