IL合集


    由於之前寫的表達式樹合集,未編寫任何注釋且是以圖片的形式展現給大家,在這里向各位看官道歉了,接下來為大家奉上新鮮出爐的香噴噴的IL合集,后面會持續更新,各位看官點關注不迷路,之前答應的手寫IOC以及多線程合集,目前IOC方面的困難已經解決掉,就差怎么封裝了,有想法的看官可以加QQ群6406277,四川觀察就是我,多線程方面的后面demo寫出來整理好之后,屆時會為大家奉上。,IL合集中注釋已經寫清楚,不明白可以在群里找我,好了,不多啰嗦,正文開始。

  首先出場的是兩數相加用IL實現

     Add

 #region Add
            {
                var methodAdd = typeBulder.DefineMethod("Add", MethodAttributes.Public, typeof(int), new Type[] { typeof(int), typeof(int) });
                var ilMethod = methodAdd.GetILGenerator();
                var method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
                ilMethod.Emit(OpCodes.Ldarg_1);//取出方法的第一個參數 並加載到棧上
                ilMethod.Emit(OpCodes.Ldarg_2);//取出方法的第二個參數 並加載到棧上
                ilMethod.Emit(OpCodes.Add);//將第一個和第二個參數相加,
                ilMethod.Emit(OpCodes.Stloc_0);//結果賦值給第0個本地變量
                ilMethod.Emit(OpCodes.Ldloc_0);//加載倒棧中
                ilMethod.EmitCall(OpCodes.Call, method, new Type[] { typeof(int) });//輸出
                ilMethod.Emit(OpCodes.Ldloc_0);//加載
                ilMethod.Emit(OpCodes.Ret);//返回相加后的結果
            }
            #endregion

And

 #region And
            {
                var methodAnd = typeBulder.DefineMethod("And", MethodAttributes.Public, typeof(int), new Type[] { typeof(int), typeof(int) });
                var ilMethod = methodAnd.GetILGenerator();
                var method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
                ilMethod.Emit(OpCodes.Ldarg_1);//取出方法的第一個參數 並加載到棧上
                ilMethod.Emit(OpCodes.Ldarg_2);//取出方法的第二個參數 並加載到棧上
                ilMethod.Emit(OpCodes.And);//將第一個和第二個參數相加,
                ilMethod.Emit(OpCodes.Stloc_0);//將And結果 賦值給local
                ilMethod.Emit(OpCodes.Ldloc_0);//將Local推到棧
                ilMethod.EmitCall(OpCodes.Call, method, new Type[] { typeof(int) });
                ilMethod.Emit(OpCodes.Ldloc_0);////將Local推到棧
                ilMethod.Emit(OpCodes.Ret);//返回And后的結果
            }
            #endregion

ble bgt bge等比較大小相關的

  #region Beq bgt bge ble blt
            {
                var method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
                var methodBeq = typeBulder.DefineMethod("Beq",MethodAttributes.Public,typeof(void),new Type[] { typeof(int),typeof(int)});
                var ilMethod = methodBeq.GetILGenerator();
                var labelEq = ilMethod.DefineLabel();
                var labelNotEq= ilMethod.DefineLabel();
                ilMethod.Emit(OpCodes.Ldarg_1);//取出方法的第一個參數 並加載到棧上
                ilMethod.Emit(OpCodes.Ldarg_2);//取出方法的第二個參數 並加載到棧上
                ilMethod.Emit(OpCodes.Beq, labelEq);//第一個和第二個是否相等
                ilMethod.Emit(OpCodes.Ldarg_1);//取出方法的第一個參數 並加載到棧上
                ilMethod.Emit(OpCodes.Ldarg_2);//取出方法的第二個參數 並加載到棧上
                ilMethod.Emit(OpCodes.Bge, labelNotEq);//第一個是否大於等於第二個  可以自行更換為Bgt,ble blt
                ilMethod.Emit(OpCodes.Ret);
                ilMethod.MarkLabel(labelEq);
                ilMethod.Emit(OpCodes.Ldstr, "第一個數等於第二個數");
                ilMethod.Emit(OpCodes.Call, method);
                ilMethod.Emit(OpCodes.Ret);
                ilMethod.MarkLabel(labelNotEq);
                ilMethod.Emit(OpCodes.Ldstr, "第一個數大於等於第二個數");
                ilMethod.Emit(OpCodes.Call, method);
                ilMethod.Emit(OpCodes.Ret);
            }
            #endregion

 IL構造循環代碼

  #region 循環
            {
                var method = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
                var methodInt = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
                var methodXh = typeBulder.DefineMethod("Xunhuan", MethodAttributes.Public, typeof(void), new Type[] { });
                var ilMethod = methodXh.GetILGenerator();
                var localBegin=ilMethod.DeclareLocal(typeof(int));//定義循環開始變量
                var localEnd= ilMethod.DeclareLocal(typeof(int));//結束變量
                var labelXunhuan = ilMethod.DefineLabel();//定義循環主體
                var labelEnd= ilMethod.DefineLabel();//定義結束標簽主體
                var labelBreak = ilMethod.DefineLabel();//定義中斷標簽
                ilMethod.Emit(OpCodes.Ldc_I4, 0);//將0加載到棧上
                ilMethod.Emit(OpCodes.Stloc_0);//這兩句是給第0個局部變量賦值,0
                ilMethod.Emit(OpCodes.Ldc_I4, 5);//將5加載到棧上
                ilMethod.Emit(OpCodes.Stloc, 1);//這兩句是給第1個局部變量賦值,5
                ilMethod.Emit(OpCodes.Br, labelXunhuan);//無條件跳轉到循環的label,即開始循環
                ilMethod.MarkLabel(labelEnd);//標記這段代碼是labelend的代碼
                ilMethod.Emit(OpCodes.Ldstr,"循環結束");
                ilMethod.Emit(OpCodes.Call, method);//輸出循環結束
                ilMethod.Emit(OpCodes.Ret);//返回
                ilMethod.MarkLabel(labelBreak);
                ilMethod.Emit(OpCodes.Ldstr, "循環終止");
                ilMethod.Emit(OpCodes.Call, method);//輸出循環結束
                ilMethod.Emit(OpCodes.Break);
                ilMethod.Emit(OpCodes.Ret);//返回
                ilMethod.MarkLabel(labelXunhuan);//標記是labelbegin的代碼
                ilMethod.Emit(OpCodes.Ldloc_0);//從棧中加載第0個局部變量
                ilMethod.Emit(OpCodes.Ldloc_1);//從棧中加載第1個局部變量
                ilMethod.Emit(OpCodes.Bge, labelEnd);//比較第0個是否小於等於第一個
                ilMethod.Emit(OpCodes.Ldloc_0);//加載循環的第0變量
                ilMethod.Emit(OpCodes.Call, methodInt);//打印出來
                ilMethod.Emit(OpCodes.Ldc_I4,1);//將1加載到棧上
                ilMethod.Emit(OpCodes.Ldloc_0);//從棧中加載第0個局部變量
                ilMethod.Emit(OpCodes.Add);//相加
                ilMethod.Emit(OpCodes.Stloc, 0);//結果賦值給本地0個局部變量
                ilMethod.Emit(OpCodes.Ldc_I4, 3);
                ilMethod.Emit(OpCodes.Ldloc_0);//從棧中加載第0個局部變量
                ilMethod.Emit(OpCodes.Beq, labelBreak);//比較第0個是否小於等於第一個
                ilMethod.Emit(OpCodes.Br, labelXunhuan);
               
            }

            #endregion

IL構建對象

    #region NewObj創建對象
            {
                var conTest = typeof(TestNewobj).GetConstructors().FirstOrDefault(s => s.GetParameters().Length > 0);
                DynamicMethod dynamicMethod = new DynamicMethod("CreateInstance", typeof(TestNewobj), new Type[] { typeof(int), typeof(int) });//創建一個動態方法,方法名稱,返回值,入參
                var il = dynamicMethod.GetILGenerator();
                il.Emit(OpCodes.Nop);//不做操作
                il.Emit(OpCodes.Ldarg_0);//從堆棧加載出方法的第0索引參數
                il.Emit(OpCodes.Ldarg_1);//1索引參數
                il.Emit(OpCodes.Newobj,conTest);//調用構造方法,並傳入0,1索引參數的值
                il.Emit(OpCodes.Ret);//返回創建的對象
               var objCreator = dynamicMethod.CreateDelegate(typeof(Func<int,int, TestNewobj>)) as Func<int,int, TestNewobj>;
                var result = objCreator(5,10);
                var resu = result.Add();
            }

            #endregion

IL實現TryCatch

 

    #region Try Catch
            {
                var method = typeof(Console).GetMethod("WriteLine",new Type[] { typeof(string)});//輸出字符串
                var method2 = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });//輸出數字
                var dynamicMethod = typeBulder.DefineMethod("TryEx",MethodAttributes.Public,CallingConventions.Standard, typeof(string),new Type[] {typeof(object),typeof(object) });//構造方法
                var il = dynamicMethod.GetILGenerator();
                var local = il.DeclareLocal(typeof(string));//本地string類型變量
                var ex = typeof(Exception);
                var localEx = il.DeclareLocal(ex);//本地Exception類型變量
                var str = ex.GetMethod("ToString");//tostring方法
                var exInstance = new Exception();
                var localInt = il.DeclareLocal(typeof(int));//本地int變量
                il.BeginExceptionBlock();//構造try塊
                il.Emit(OpCodes.Ldarg_1);//加載第一個變量
                il.Emit(OpCodes.Unbox_Any,typeof(int));//加載第一個變量並且將obj轉為int
                il.Emit(OpCodes.Ldarg_2);//加載第二個變量並且將obj轉為int
                il.Emit(OpCodes.Unbox_Any, typeof(int));//加載第二個變量並且將obj轉為int
                il.Emit(OpCodes.Add);//相加
                il.Emit(OpCodes.Stloc,2);//賦值給本地第二個int變量
                il.Emit(OpCodes.Ldloc, 2);//加載本地第二個int變量
                il.Emit(OpCodes.Call, method2);//輸出
                il.Emit(OpCodes.Ldstr, "正常執行");//加載字符串
                il.Emit(OpCodes.Stloc,0);//賦值給第0個變量
                il.BeginCatchBlock(ex);//構造catch塊
                il.Emit(OpCodes.Stloc,1);//將ex賦值給本地exception變量
                il.Emit(OpCodes.Ldloc,1);
                il.Emit(OpCodes.Callvirt, str);//加載本地ex變量並且tostring一下
                il.Emit(OpCodes.Call, method);//輸出異常信息
                il.Emit(OpCodes.Ldstr, "非正常執行");//加載結果字符串
                il.Emit(OpCodes.Stloc, 0);//賦值給第0個變量
                il.Emit(OpCodes.Rethrow);//拋出異常 就是throw
                il.EndExceptionBlock();//結束catch塊
                il.Emit(OpCodes.Ldloc,0);//加載第0個字符串變量
                il.Emit(OpCodes.Ret);//返回結果
                var type = typeBulder.CreateType();
                var instance = Activator.CreateInstance(type);
                var mh = type.GetMethod("TryEx");
               var ttt= mh.Invoke(instance, new object[] { 10,new TestNewobj(1,1)});//此處可以修改為其他類型的變量,testnewobj是我測試用
            }
            #endregion

好了,今天的分享就結束了,后續會持續更新,歡迎大家關注,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM