.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

这篇具有很好参考价值的文章主要介绍了.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言:

经过前面几篇的学习,我们了解到指令的大概分类,如:

参数加载指令,该加载指令以 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:无符号。

例如:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

多数指令都带有这两个后缀,理解这两个后缀的意思,可以快速理解所有该后缀指令。 

1、算术运算指令:

Add 指令:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

示例代码:

 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);     // 返回该值

对应代码:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

其它指令使用方式一样,省去重复举例。

Add 指令对应C#代码:+
Sub 指令对应C#代码:-
Mul 指令对应C#代码:*
Div 指令对应C#代码:/

2、逻辑运算指令:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

 示例代码:

ILGenerator il = methodBuilder.GetILGenerator();

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

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

对应代码:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

使用方式和算术指令运行其实一致:

 And 指令对应C#代码:&
  Or  指令对应C#代码:|
 Xor  指令对应C#代码:^

3、位操作指令:

Shl 指令:左移指令,Shift Left 的简写

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

示例代码:

ILGenerator il = methodBuilder.GetILGenerator();

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

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

对应代码: 

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

使用方式,需要在第二个参数,指定要位移的位数。

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

Not 指令:按位取反

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

示例代码:

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);     // 返回该值

对应代码:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

右移操作的方式和左移一样,而 Not 指令则不需要第二个参数:

Shl 指令对应C#代码:<<
Shr 指令对应C#代码:>>
Not 指令对应C#代码:~

4、比较操作指令:

Ceq 指令:比较两个值

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

 示例代码:

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();

对应代码:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

运行结果:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

其它两个指令使用方式和 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);     // 返回该值

对应代码:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

用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);     // 返回该值

对应代码:

.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

性能小细节提醒:

平时我们写代码,涉及 >= 或 <= 的整数字判断时候:

比如:a>=2(需要两条指令),可以写成 a>3(只要一条指令)。

总结:

在.NET Emit编程中,我们探讨了运算操作指令的重要性和应用。

这些指令包括各种数学运算、位操作和比较操作,能够在动态生成的代码中实现对数据的处理和操作。

通过这些指令,开发人员可以灵活地进行算术运算、逻辑运算和比较操作,从而实现各种复杂的算法和逻辑。

在实际应用中,我们可以利用这些指令来实现诸如加密算法、数值计算、逻辑判断、数据压缩等功能。

通过深入理解和熟练运用这些运算操作指令,开发人员可以提高动态代码生成的效率和灵活性,从而更好地满足各种编程需求。

同时,对ILGenerator指令方法的进一步学习也能够帮助开发人员更加灵活地控制动态生成的代码,实现更复杂的功能和逻辑。

本篇之后,将进入第七部分:实战项目文章来源地址https://www.toymoban.com/news/detail-855016.html

到了这里,关于.NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • .NET Emit 入门教程:第六部分:IL 指令:9:详解 ILGenerator 指令方法:运算操作指令(指令篇结束)

    经过前面几篇的学习,我们了解到指令的大概分类,如: 参数加载指令,该加载指令以 Ld 开头,将参数加载到栈中,以便于后续执行操作命令。 参数存储指令,其指令以 St 开头,将栈中的数据,存储到指定的变量中,以方便后续使用。 创建实例指令,其指令以 New 开头,

    2024年04月22日
    浏览(27)
  • .NET Emit 入门教程:第三部分:构建模块(Module)

    在这一部分中,我们将深入讨论动态程序集中模块的概念以及如何构建和管理模块。 模块是动态程序集中的基本单位,它类似于一个独立的代码单元,可以包含类型、方法、字段等成员。 在动态程序集中,模块扮演着组织代码和实现代码复用的关键角色。 它们允许开发人员

    2024年03月22日
    浏览(49)
  • .NET Emit 入门教程:第四部分:构建类型(Type)

    在动态生成代码的过程中,构建类型(Type)是至关重要的一步。 通过使用 Emit 中的 TypeBuilder,我们可以定义和创建各种类型,包括类、结构体和接口。 本节将深入探讨如何使用 TypeBuilder 动态构建类型,并介绍其在实际应用中的重要性。 通过学习本系列之前的文章,我们可

    2024年03月25日
    浏览(28)
  • .NET Emit 入门教程:第二部分:构建动态程序集(追加构建静态程序集教程)

    在本部分中,我们将深入探讨如何使用C# Emit 来创建动态程序集。 动态程序集是在运行时生成的,为我们提供了一种灵活、动态地构建和加载程序集的能力。 程序集是.NET中的基本部署单位,它包含了可执行代码、资源、元数据等信息,是.NET应用程序的基本组成单元之一。

    2024年03月21日
    浏览(35)
  • 【Git 入门教程】第六节、Git高级操作

    Git是一种非常强大的分布式版本控制系统,可以帮助开发者轻松地管理和协调代码库。在本文中,我们将介绍一些Git高级操作,包括如何管理Git仓库、标签、子模块和忽略文件。 Git提供了许多命令来管理本地Git仓库。以下是一些常用的管理命令: 初始化一个新的Git仓库: 查

    2024年02月05日
    浏览(40)
  • Odoo17入门教程第六章 UI

    现在我们已经创建了新模型及其 相应的,是时候了 与用户界面交互。 在本章结束时,我们将创建几个菜单以访问默认列表 和窗体视图。 参考 :与此主题相关的文档可以在数据文件中找到。 在第五章:安全性-简介中,我们通过 CSV 文件添加了数据。CSV 当要加载的数据具有

    2024年04月23日
    浏览(34)
  • 掌握Linux指令和权限:一个入门教程

    语法格式 :ls [选项][目录或者文件] 功能 :对于目录,该命令列出该目录下的所有子目录与文件。对于文件,将列出文件名以及其他信息。 a 列出目录下的所有文件,包括以 . 开头的隐含文件。 -d 将目录象文件一样显示,而不是显示其下的文件。 如:ls –d 指定目录 -i 输出文

    2023年04月23日
    浏览(29)
  • C语言快速入门教程1快速入门 2指令 3条件选择

    C是一种编程语言,1972年由Dennis Ritchie在美国AT T的贝尔实验室开发。C语言变得很流行,因为它很简单,很容易使用。今天经常听到的一个观点是--\\\"C语言已经被C++、Python和Java等语言所取代,所以今天何必再去学习C语言\\\"。我很不赞同这种观点。这有几个原因。这些原因如下:

    2024年02月03日
    浏览(34)
  • C语言入门教程,C语言学习教程(第三部分:C语言变量和数据类型)二

    前面我们多次提到了字符串,字符串是多个字符的集合,它们由 \\\" \\\" 包围,例如 \\\"http://c.biancheng.net\\\" 、 \\\"C语言中文网\\\" 。字符串中的字符在内存中按照次序、紧挨着排列,整个字符串占用一块连续的内存。 当然,字符串也可以只包含一个字符,例如 \\\"A\\\" 、 \\\"6\\\" ;不过为了操作方

    2024年01月17日
    浏览(40)
  • ESP8266-01s入门:上报和下发数据控制单片机 AT指令讲解和上云 烧录AT固件与OneNET MQTT通信教程包含MQTT.fx1.7.1教程(微信小程序通信单片机前置任务)

    本项目教程总共分为四节 1.创建OneNET新版MQTT设备:为微信小程序与单片机通信打基础(微信小程序通信单片机前置任务) 2.(当前文章)ESP8266-01s入门:烧录AT固件与OneNET MQTT通信教程包含MQTT.fx1.7.1教程(微信小程序通信单片机前置任务) 3.物联网实践教程:微信小程序结合

    2024年02月04日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包