【深入浅出.Net IL】1.一个For循环引发的IL

1.准备工作

(1)新建一个project

using System;

namespace newArr
{
    class Program
    {
        static void Main(string[] args)
        {
            char[] arrchars = new char[5];
            for (int i = 0; i < 5; i++)
            {
                arrchars[i] = ‘a‘;
                Console.WriteLine(arrchars[i]);
            }
            Console.WriteLine("123");
        }
    }
}

(2)编译并生成exe文件

用IL Disassembler 工具打开exe文件

2.分析IL代码

打开Main方法

分析指令

1.初始化 local variable List

.locals init ([0] char[] arrchars,

[1] int32 i,

[2] bool CS$4$0000)   

2.IL_0000:  nop

空操作

3.IL_0001:  ldc.i4.5

将整数5存放到Evaluation stack的顶部

4. IL_0002:  newarr     [mscorlib]System.Char

创建一个数组

5.  IL_0007:  stloc.0

将Evalution Stack 顶部值弹出放在第一个变量arrchars中

6.  IL_0008:  ldc.i4.0

将整数0压入到Evalution Stack

7.  IL_0009:  stloc.1

将Evalution Stack顶部的值0弹出存放到Local variable list的第2个变量i中

8.  IL_000a:  br.s       IL_0020

无条件跳转到地址:IL_0020

9.IL_0020:  ldloc.1

将Local variable list中的第2个变量的值copy一份到Evaluation stack的顶部

10.  IL_0021:  ldc.i4.5

将整数5存放到Evaluation Stack的顶部

11.IL_0022:  clt

比较Evaluation Stack顶部的两个值,如果0<5则将1存放到Evaluation Stack顶部,否则将0存放到Evaluation Stack顶部

12.  IL_0024:  stloc.2

将Evaluation Stack顶部的值1弹出存放到Local variable list的第二个变量中

13.  IL_0025:  ldloc.2

将Local variable list中的第二个变量的值copy一份到Evaluation stack的顶部

14.  IL_0026:  brtrue.s   IL_000c

判断Evaluation Stack顶部的值为true、非空或非零,则跳转到IL_000c否则顺序往下执行。因为顶部的值为1,所以跳转到地址IL_000c

15.  IL_000c:  nop

空操作

16.  IL_000d:  ldloc.0

将Local variable list中的第1个变量的值copy一份到Evaluation Stack的顶部

17.  IL_000e:  ldloc.1

将Local variable list中的第2个变量的值copy一份到Evaluation Stack的顶部

18.IL_000f:  ldc.i4.s   97

97对应的ACISS 码为‘a‘,将‘a‘存放到Evaluation Stack的顶部

19.  IL_0011:  stelem.i2

将arrchars[0]赋值为‘a‘,将arrchars[0]的值存放到Local variable list的变量arrchars中

20.  IL_0012:  ldloc.0

将Local variable list中的第1个变量的值copy一份到Evaluation Stack的顶部

21. IL_0013:  ldloc.1

将Local variable list中的第2个变量的值copy一份到Evaluation Stack的顶部

22.  IL_0014:  ldelem.u2

将arrchars[0]压入Evaluation Stack的顶部

23.  IL_0015:  call       void [mscorlib]System.Console::WriteLine(char)

调用System.Console.WriteLine(char)方法打印‘a‘

24.  IL_001a:  nop

空操作

25.  IL_001b:  nop

空操作

26.  IL_001c:  ldloc.1

将Local variable list中的第2个变量的值copy一份到Evaluation Stack的顶部

27.  IL_001d:  ldc.i4.1

将整数1压入Evaluation Stack的顶部

28. IL_001e:  add

将Evaluation Stack顶部的两个值相加,将结果1压入Evaluation Stack的顶部

29.  IL_001f:  stloc.1

将Evaluation Stack顶部的值1弹出存放到Local variable list的第二个变量中

30.重复执行下面的指令

IL_0020:  ldloc.1

IL_0021:  ldc.i4.5

IL_0022:  clt

IL_0024:  stloc.2

IL_0025:  ldloc.2

IL_0026:  brtrue.s   IL_000c

31.当Local variable list的第二个变量等于5时,

执行IL_0026:  brtrue.s   IL_000c  指令,顺序往下执行

32. IL_0028:  ldstr      "123"

将字符串"123"压入压入Evaluation Stack的顶部

33.  IL_002d:  call       void [mscorlib]System.Console::WriteLine(string)

调用Sys.Console.WriteLine(string)方法,打印"123"

34.  IL_0032:  nop

空操作

35.  IL_0033:  ret

返回

至此,这个for循环的代码的反编译代码就分析完了,请期待后续的文章。谢谢大家阅读本文章。

时间: 2024-10-10 09:14:14

【深入浅出.Net IL】1.一个For循环引发的IL的相关文章

一个多线程问题引发的血案-(代码段执行完毕,子进程未执行完毕导致段错误)

今天遇到一个问题,gdb执行程序完全没有问题,但直接执行就会段错误,百思不得其解,各种纠结,各种搜索引擎都试了一遍,无果!后来问题还是被我自己挖出来了. 看下边一段代码: int TaskSendControl() { pthread_t prov_thread[CLIENT_NUM]; int prov[CLIENT_NUM]; for(int i=0; i< CLIENT_NUM; i++) { prov[i] = i; if( pthread_create(&prov_thread[i

一个回车符引发的问题思考

在维护和开发通信类软件产品的过程中,经常需要处理一些软件故障问题.在问题刚出现的时候,大家可能显得手足无措,有一种天都要塌下来的感觉.但在问题原因找到之后,大家又会觉得问题原因非常的简单,要是当初开发的时候仔细一点,是不会犯这样的低级错误的.最近,本人就遇到了一个回车符引发的问题. 近日,在开发某软件版本时需要对文件进行操作,在代码中使用了Linux C语言中的opendir函数,但是该函数始终返回NULL,提示文件路径不存在. 本人查了一下该函数的具体情况.opendir函数的原型为: DIR

一个二级菜单引发的血案

近期发现自己css不是很好,于是又看了一遍<css权威指南>.总感觉自己抓不到重点.弃疗中...于是看看其他书.然后学妹跟我说她的二级菜单写得很乱.当时我心里就在想二级菜单,有何难?自认为10分钟能搞定.跟她要效果图并很自大的说了句“等会儿,我写个简单的”.于是血案由此引发... 二级菜单要实现的原效果图是: (如发现雷同,不是巧合,是我从别的网页上截屏下来的 ~_~).既然说了简单,肯定效果没这么精美.但是至少基本效果和原理要实现. 10分钟过去了....15分钟过去了....这个“等会儿”

使用一个for循环将N*N的二维数组的所有值置1

<?php // 使用一个for循环将N*N的二维数组的所有值置1 $n = 3; $a = []; for($i=0;$i<$n*$n;$i++){ $a[$i/$n][$i%$n] = 1; } print_r($a);

android:一个Open键引发的问题!!

1.问题简介 首先描述一下问题,当我们安装完APP的时候,界面会显示两个按钮,一个完成键,一个Open键,点击Open键之后,进入应用.此时,我们点击HOME键,程序将会后台.然后再点击该桌面上应用程序的图标,巨大的BUG出现了:app会重新启动!而不是将原来的界面onresume!如果你的应用对多次启动不敏感,这道没什么,但是,如果你的应用对多次启动很敏感,你就必须做处理了. 2.解决方案 首先分析问题成因,在android目前的系统下(最新的为4.4.3),点击Open键和点击图标启动时,I

一个for循环打印二维数组

#include<stdio.h> #define MAXX 2 #define MAXY 3 void printarray() { int Arr[MAXX][MAXY] = {1,2,3,4,5,6}; for(int i = 0;i< MAXX*MAXY;i++) { printf("%d\n",Arr[i/MAXY][i%MAXY]); ///注意,一直没管MAXX什么事,在计算这一类的时候,最容易出问题 } } 一个for循环打印二维数组

易语言怎样写双线程?一个线程循环找图。一个线程循环按键F2。

易语言怎样写双线程? 一个线程循环找图.一个线程循环按键F2. // .程序集变量 参数, 整数型 .程序集变量 线程句柄1, 整数型 .程序集变量 线程句柄2, 整数型 启动线程 (&子程序1, 参数,线程句柄1) 启动线程 (&子程序2, ,线程句柄2) // .子程序 子程序1 .参数 参数1, 整数型 信息框 (参数1, 0, ) 信息框 (“这是线程1的例子”, 0, ) // .子程序 子程序2 信息框 (“这是线程2的例子”, 0, ) // // 注意: 凡调用到COM接口

一个分号所引发的错误

最近复习到数据结构中图这一章节了.今天复习到图的遍历了. 代码非常简单 1 void print(Graph *G) 2 { 3 int i, j; 4 for(i = 1; i <= G->vexNum; i++) 5 { 6 for(j = 1; j <= G->vexNum; j++); 7 { 8 printf("%d ", G->vex[i][j]); 9 } 10 printf("\n"); 11 } 12 for (i =

SharePoint 自定义的列表页面中添加javascript的一个 For循环语句后,该页面就打不开了。

一个sharepoint 2013的普通的列表的自定义新建页面,我在其中新添加几行javascript代码后页面就打不开了.如图所示: 真是一言不合,友谊的页面说打不开就打不开啊.后来慢慢比对发现是因为Javascript中有一个For循环,当把这个for循环去掉,页面就可以正常打开,而当把for循环加上,页面直接就打不开了. 原因: 列表的自定义页面一般都是XSL格式的,for可能在里面是个比较特殊的关键字,所以就造成解析困难了. 解决方法: 1.可以用jquery的each方法代替for循环