.NET Emit 入門教程:第六部分:IL 指令:9:詳解 ILGenerator 指令方法:運算操作指令(指令篇結束)

来源:https://www.cnblogs.com/cyq1162/p/18133417
-Advertisement-
Play Games

在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...


前言:

經過前面幾篇的學習,我們瞭解到指令的大概分類,如:

參數載入指令,該載入指令以 Ld 開頭,將參數載入到棧中,以便於後續執行操作命令。

參數存儲指令,其指令以 St 開頭,將棧中的數據,存儲到指定的變數中,以方便後續使用。

創建實例指令,其指令以 New 開頭,用於在運行時動態生成並初始化對象。

方法調用指令,該指令以 Call 開頭,用於在運行時調用其它方法。

支條件指令,該指令通常以 Br、或 B、C 開頭,用於在運行分支條件時跳轉指令。

類型轉換指令,該指令通常以 Cast、Conv 開頭或box結尾,用於在運行時對類型進行轉換。

本篇介紹運算操作指令,介紹完後,將結束指令篇。

第六部分:IL指令完整大綱目錄如下:

.NET Emit 入門教程:第六部分:IL 指令:1:概要介紹

.NET Emit 入門教程:第六部分:IL 指令:2:詳解 ILGenerator 輔助方法

.NET Emit 入門教程:第六部分:IL 指令:3:詳解 ILGenerator 指令方法:參數載入指令

.NET Emit 入門教程:第六部分:IL 指令:4:詳解 ILGenerator 指令方法:參數存儲指令

.NET Emit 入門教程:第六部分:IL 指令:5:詳解 ILGenerator 指令方法:創建實例指令

.NET Emit 入門教程:第六部分:IL 指令:6:詳解 ILGenerator 指令方法:方法調用指令

.NET Emit 入門教程:第六部分:IL 指令:7:詳解 ILGenerator 指令方法:分支條件指令

.NET Emit 入門教程:第六部分:IL 指令:8:詳解 ILGenerator 指令方法:類型轉換指令

.NET Emit 入門教程:第六部分:IL 指令:9:詳解 ILGenerator 指令方法:運算操作指令(指令篇結束)

運算操作指令介紹:

在.NET Emit 編程中,運算操作指令是一類關鍵的IL(Intermediate Language)指令,用於在動態生成的代碼中執行各種數學運算、位操作和比較操作。

這些指令允許開發人員對操作數進行加法、減法、乘法、除法、邏輯與、邏輯或、邏輯非、位與、位或、位異或、左移、右移以及比較等操作。

通過運算操作指令,開發人員能夠在動態生成的代碼中實現各種算術運算、邏輯運算和位操作,從而更靈活地處理數據和實現複雜的邏輯。

這些指令為動態代碼生成提供了強大的功能,使得開發人員能夠根據需要生成高效且功能豐富的代碼。

運算操作指令的分類:

讓我們按照分類逐一介紹各種指令以及它們的詳細用途。

  1. 算術運算指令:

    • add(加法):將兩個值相加,並將結果推送到計算棧上。主要用於執行整數和浮點數的加法操作。
    • sub(減法):將一個值減去另一個值,並將結果推送到計算棧上。用於執行整數和浮點數的減法操作。
    • mul(乘法):將兩個值相乘,並將結果推送到計算棧上。用於執行整數和浮點數的乘法操作。
    • div(除法):將一個值除以另一個值,並將結果推送到計算棧上。用於執行整數和浮點數的除法操作。
  2. 邏輯運算指令:

    • and(與):對兩個整數進行按位與操作,並將結果推送到計算棧上。用於執行邏輯與操作。
    • or(或):對兩個整數進行按位或操作,並將結果推送到計算棧上。用於執行邏輯或操作。
    • xor(異或):對兩個整數進行按位異或操作,並將結果推送到計算棧上。用於執行邏輯異或操作。
  3. 位操作指令:

    • shl(左移):將一個整數向左移動指定的位數,並將結果推送到計算棧上。用於執行左移操作。
    • shr(右移):將一個整數向右移動指定的位數,並將結果推送到計算棧上。用於執行算術右移操作。
    • not(非):對一個整數進行按位取反操作,並將結果推送到計算棧上。用於執行按位取反操作。
  4. 比較操作指令:

    • ceq(相等比較):比較兩個值是否相等,並將結果推送到計算棧上。用於執行相等比較操作。
    • clt(小於比較):比較一個值是否小於另一個值,並將結果推送到計算棧上。用於執行小於比較操作。
    • cgt(大於比較):比較一個值是否大於另一個值,並將結果推送到計算棧上。用於執行大於比較操作。

這些指令提供了豐富的功能,可以用於執行各種數學運算、邏輯運算、位操作和比較操作,從而實現各種複雜的編程邏輯。在動態生成的代碼中,開發人員可以根據具體需求使用這些指令來實現所需的功能。

接下來,我們對一個指令分類,分別給出一個示例,來介紹它們的基本用法。

對於運行指令,有兩個指令尾碼:

_ovf: 進行溢出檢查。

_un:無符號。

例如:

多數指令都帶有這兩個尾碼,理解這兩個尾碼的意思,可以快速理解所有該尾碼指令。 

1、算術運算指令:

Add 指令:

示例代碼:

 MethodBuilder methodBuilder = tb.DefineMethod("MathTo", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(int),typeof(int) });

 ILGenerator il = methodBuilder.GetILGenerator();

 il.Emit(OpCodes.Ldarg_0);
 il.Emit(OpCodes.Ldarg_1);
 il.Emit(OpCodes.Add_Ovf_Un);

 il.Emit(OpCodes.Ret);     // 返回該值

對應代碼:

其它指令使用方式一樣,省去重覆舉例。

Add 指令對應C#代碼:+
Sub 指令對應C#代碼:-
Mul 指令對應C#代碼:*
Div 指令對應C#代碼:/

2、邏輯運算指令:

 示例代碼:

ILGenerator il = methodBuilder.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.And);

il.Emit(OpCodes.Ret);     // 返回該值

對應代碼:

使用方式和算術指令運行其實一致:

 And 指令對應C#代碼:&
  Or  指令對應C#代碼:|
 Xor  指令對應C#代碼:^

3、位操作指令:

Shl 指令:左移指令,Shift Left 的簡寫

示例代碼:

ILGenerator il = methodBuilder.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4,2);
il.Emit(OpCodes.Shl);

il.Emit(OpCodes.Ret);     // 返回該值

對應代碼: 

使用方式,需要在第二個參數,指定要位移的位數。

右移操作的方式和左移一樣。

Not 指令:按位取反

示例代碼:

MethodBuilder methodBuilder = tb.DefineMethod("MathTo", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(int) });

ILGenerator il = methodBuilder.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Not);

il.Emit(OpCodes.Ret);     // 返回該值

對應代碼:

右移操作的方式和左移一樣,而 Not 指令則不需要第二個參數:

Shl 指令對應C#代碼:<<
Shr 指令對應C#代碼:>>
Not 指令對應C#代碼:~

4、比較操作指令:

Ceq 指令:比較兩個值

 示例代碼:

var dynamicMethod = new DynamicMethod("ConvertTo", typeof(bool), new Type[] { typeof(int), typeof(float) }, typeof(AssMethodIL_Condition));

ILGenerator il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ceq);

il.Emit(OpCodes.Ret);     // 返回該值

var result = dynamicMethod.Invoke(null, new object[] { 11, 11 });
Console.WriteLine(result);
Console.Read();

對應代碼:

運行結果:

其它兩個指令使用方式和 Ceq 一致:

Ceq 指令對應C#代碼:==
Clt 指令對應C#代碼:<
Cgt 指令對應C#代碼:>

如何實現 >= 或 <=

由於沒有對應的指令,所以需要用點小技巧組合,來實現該代碼:

用Clt + Ceq 指令實現:>=

ILGenerator il = methodBuilder.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Clt);

il.Emit(OpCodes.Ldc_I4, 0);
il.Emit(OpCodes.Ceq);

il.Emit(OpCodes.Ret);     // 返回該值

對應代碼:

用Cgt + Ceq 指令實現:<=

ILGenerator il = methodBuilder.GetILGenerator();

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Cgt);

il.Emit(OpCodes.Ldc_I4, 0);
il.Emit(OpCodes.Ceq);

il.Emit(OpCodes.Ret);     // 返回該值

對應代碼:

性能小細節提醒:

平時我們寫代碼,涉及 >= 或 <= 的整數字判斷時候:

比如:a>=2(需要兩條指令),可以寫成 a>3(只要一條指令)。

總結:

在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。

這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。

通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯。

在實際應用中,我們可以利用這些指令來實現諸如加密演算法、數值計算、邏輯判斷、數據壓縮等功能。

通過深入理解和熟練運用這些運算操作指令,開發人員可以提高動態代碼生成的效率和靈活性,從而更好地滿足各種編程需求。

同時,對ILGenerator指令方法的進一步學習也能夠幫助開發人員更加靈活地控制動態生成的代碼,實現更複雜的功能和邏輯。

本篇之後,將進入第七部分:實戰項目

版權聲明:本文原創發表於 博客園,作者為 路過秋天 本文歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則視為侵權。
個人微信公眾號
Donation(掃碼支持作者):支付寶:
Donation(掃碼支持作者):微信:

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天電腦重啟之後,發現 visual studio 2022 的智能提示與報錯經常性不好用,不光不能在正常時候提示代碼錯誤信息,甚至在編譯過後也不提示錯誤。反覆重啟,剛開始正常,隔一會兒就會提示什麼什麼功能不可用,點開打開詳情,提示:StreamJsonRpc.ConnectionLostExcep ...
  • 通常情況下,PDF文件是不可編輯的,但PDF表單提供了一些可編輯區域,允許用戶填寫和提交信息。PDF表單通常用於收集信息、反饋或進行線上申請,是許多行業中數據收集和交換的重要工具。 PDF表單可以包含各種類型的輸入控制項,如文本框、覆選框、下拉菜單、單選按鈕等。本文將介紹如何使用C# 和一個免費.NE ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:本文代碼示例演示瞭如何在WPF中使用LiveCharts庫創建動態條形圖。通過創建數據模型、ViewModel和在XAML中使用`CartesianChart`控制項,你可以輕鬆實現圖表的數據綁定和動態更新。我將通過清晰的步驟指南包括詳細的中文註釋,幫助你快速理解並應用這一功能。 先上效果: 在 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • 概述:本示例演示了在WPF應用程式中實現多語言支持的詳細步驟。通過資源字典和數據綁定,以及使用語言管理器類,應用程式能夠在運行時動態切換語言。這種方法使得多語言支持更加靈活,便於維護,同時提供清晰的代碼結構。 在WPF中實現多語言的一種常見方法是使用資源字典和數據綁定。以下是一個詳細的步驟和示例源代 ...
  • 描述(做一個簡單的記錄): 事件(event)的本質是一個委托;(聲明一個事件: public event TestDelegate eventTest;) 委托(delegate)可以理解為一個符合某種簽名的方法類型;比如:TestDelegate委托的返回數據類型為string,參數為 int和 ...
  • 1、AOT適合場景 Aot適合工具類型的項目使用,優點禁止反編 ,第一次啟動快,業務型項目或者反射多的項目不適合用AOT AOT更新記錄: 實實在在經過實踐的AOT ORM 5.1.4.117 +支持AOT 5.1.4.123 +支持CodeFirst和非同步方法 5.1.4.129-preview1 ...
  • 總說周知,UWP 是運行在沙盒裡面的,所有許可權都有嚴格限制,和沙盒外交互也需要特殊的通道,所以從根本杜絕了 UWP 毒瘤的存在。但是實際上 UWP 只是一個應用模型,本身是沒有什麼許可權管理的,許可權管理全靠 App Container 沙盒控制,如果我們脫離了這個沙盒,UWP 就會放飛自我了。那麼有沒... ...
  • 目錄條款17:讓介面容易被正確使用,不易被誤用(Make interfaces easy to use correctly and hard to use incorrectly)限制類型和值規定能做和不能做的事提供行為一致的介面條款19:設計class猶如設計type(Treat class de ...
  • title: 從零開始:Django項目的創建與配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 後端開發 tags: Django WebDev Python ORM Security Deployment Op ...
  • 1、BOM對象 BOM:Broswer object model,即瀏覽器提供我們開發者在javascript用於操作瀏覽器的對象。 1.1、window對象 視窗方法 // BOM Browser object model 瀏覽器對象模型 // js中最大的一個對象.整個瀏覽器視窗出現的所有東西都 ...