.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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...