C#支持的位运算是与、或、异或、取反、左移、右移,它们对应的指令是
And、Or、Xor、Not、Shl、Shr。

取反运算只需要一个操作数,生成步骤是
1.生成加载变量
2.生成取反指令
实例代码:

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

其它五个运算都需要两个参数,它们的通用步骤
1.生成加载左边变量
2.生成加载右边变量
3.生成运算指令

实例:

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

完整的程序如下:

using System;
using System.Reflection;
using System.Reflection.Emit; namespace LX1_ILDemo
{
class Demo17_BitOP
{
static string binaryName = "Demo17_BitOP.exe";
static string namespaceName = "LX1_ILDemo";
static string typeName = "BitOPDemo"; static AssemblyBuilder assemblyBuilder;
static ModuleBuilder moduleBuilder;
static TypeBuilder typeBuilder;
static MethodBuilder mainMethod;
static MethodBuilder testMethod; static void Emit_Test()
{
testMethod = typeBuilder.DefineMethod("TestOP", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { typeof(int), typeof(int) });
var println = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) });
var ilGenerator = testMethod.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Not);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.And);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Or);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldarg_1);
ilGenerator.Emit(OpCodes.Xor);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldc_I4_2);
ilGenerator.Emit(OpCodes.Shl);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Ldc_I4_2);
ilGenerator.Emit(OpCodes.Shr);
ilGenerator.Emit(OpCodes.Call, println); ilGenerator.Emit(OpCodes.Ret);
} public static void Generate()
{
InitAssembly();
typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public);
Emit_Test();
GenerateMain();
assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);
SaveAssembly();
Console.WriteLine("生成成功");
} static void GenerateMain()
{
mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public
| MethodAttributes.Static, typeof(void), new Type[] { });
var ilGenerator = mainMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldc_I4,);
ilGenerator.Emit(OpCodes.Ldc_I4,);
ilGenerator.Emit(OpCodes.Call, testMethod); ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("ReadKey", new Type[] { }));
ilGenerator.Emit(OpCodes.Pop);
ilGenerator.Emit(OpCodes.Ret);
} static void InitAssembly()
{
AssemblyName assemblyName = new AssemblyName(namespaceName);
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);
} static void SaveAssembly()
{
Type t = typeBuilder.CreateType(); //完成Type,这是必须的
assemblyBuilder.Save(binaryName);
}
}
}

MSIL实用指南-位运算的更多相关文章

  1. MSIL实用指南-比较运算

    数值的比较就是大于.小于.等于.大于等于.小于等于.不等于,它们的运算结果都是布尔值.大于.小于.等于有直接对应的指令,分别是Cgt.Clt.Ceq.大于等于.小于等于.不等于没有直接对应的指令,它的 ...

  2. MSIL实用指南-数学运算

    C#支持的数学运算是加.减.乘.除.取模,它们对应的指令是Add.Sub.Mul.Div.Rem. 这五个运算都需要两个参数,它们的通用步骤1.生成加载左边变量2.生成加载右边变量3.生成运算指令 实 ...

  3. MSIL实用指南-生成索引器

    MSIL实用指南-生成索引器 索引器是一种特殊的属性,它有参数的,也有get和set方法,属性名称一般是"Item",并且方法名称一般名称是"get_Item" ...

  4. MSIL实用指南-Action的生成和调用

    MSIL实用指南-Action的生成和调用 System.Action用于封装一个没有参数没有返回值的方法.这里生成需要Ldftn指令. 下面讲解怎生成如下的程序. class ActionTest ...

  5. MSIL实用指南-逻辑运算

    逻辑运算有三种:与.或.非.实现它们可以用位运算指令And.Or.Not等三个指令.它们的使用方法和位运算一致. 完整的程序如下: using System; using System.Reflect ...

  6. MSIL实用指南-加载bool、sbyte、byte、char、short等值

    这一篇讲解怎么加载bool值.sbyte值.byte值.char值.short值. 加载bool值在.NET程序实际运行中,是没有true和false值的,实际上是以1和0表示它们,加载它们的指令是L ...

  7. MSIL实用指南-局部变量的声明、保存和加载

    这一篇讲解方法内的局部变量是怎么声明.怎样保存.怎样加载的. 声明局部变量声明用ILGenerator的DeclareLocal方法,参数是局部变量的数据类型,得到一个局部变量对应的创建类LocalB ...

  8. MSIL实用指南-加载int值

    这一篇讲的是怎样加载整数值到运算栈上.这一类的指令都是以Ldc_I4开头. Ldc_I4类OpCodes的Ldc_I4字段的功能是把一个int值压入运算栈上.它的使用方法是ilGenerator.Em ...

  9. MSIL实用指南-IL版hello world

    我们学习编程开始时,一般用输出"hello world"的一段程序. C#版的"hello world"是 using System; namespace L0 ...

随机推荐

  1. 💡我们的表单解决方案 el-form-renderer

    前言 本文将介绍我们的表单解决方案 @femessage/el-form-renderer,展示我们在 Vue 技术栈下,我们是如何处理以下问题的: 表单项动态显示或隐藏 表单数据联动 表单输入/输出 ...

  2. textarea的拖拽怎么解决

    textarea文本域在页面中是可以拖动的,即时你给了固定的宽度和高度,但这在我们页面布局中,使我们不需要的,因为可拖拽很多时候会影响我们页面的布局和整体的美观度. css3提供了一个resize属性 ...

  3. 10分钟了解分布式CAP、BASE理论

    CAP理论 2000年7月,Eric Brewer教授提出CAP猜想:2年后,Seth Gilbert和Nancy Lynch从理论上证明了CAP:之后,CAP理论正式成为分布式计算领域的公认定理. ...

  4. Drools规则引擎-如果判断某个对象中的集合是否包含指定的值

    规则引擎集合相关处理 在实际生产过程中,有很多关于集合的处理场景,比如一个Fact对象中包含有一个集合,而需要判断该集合是否包含某个值.而Drools规则引擎也提供了多种处理方式,比如通过from.c ...

  5. SQLServer2000同步复制技术实现步骤

    SQLServer2000同步复制技术实现步骤 一. 预备工作 1.发布服务器,订阅服务器都创建一个同名的windows用户,并设置相同的密码,做为发布快照文件夹的有效访问用户 --管理工具 --计算 ...

  6. Go orm框架gorm学习

    之前咱们学习过原生的Go连接MYSQL的方法,使用Go自带的"database/sql"数据库连接api,"github.com/go-sql-driver/mysql& ...

  7. 5月29日 Java性能调优指南 读后感

    并行垃圾收集器 串行垃圾收集器 并发标记清除(CMS)垃圾收集器 Garbage First(G1)垃圾收集器 没有深入的学习G1的原理,只是看了大概的思想; SA工具:待学习

  8. 5.MySQL数据库操作步骤

    第一步:登录到MySQL服务器 第二步:选择当前要操作的数据库 第三步:设置请求和返回数据的字符集 第四步:执行SQL语句 l 增加记录:INSERT INTO news(title,content) ...

  9. abp(net core)+easyui+efcore实现仓储管理系统——使用 WEBAPI实现CURD (十四)

    abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...

  10. Go-json解码到结构体

    废话不多说,直接干就得了,上代码 package main import ( "encoding/json" "fmt" ) type IT struct { ...