可以通过编程方式获得.NET编译器可以生成的所有IL指令的列表吗?
答案 0 :(得分:2)
System.Reflection.Emit.OpCodes类可以使用它们。
答案 1 :(得分:1)
IL指令在ECMA-335 - Common Language Infrastucture标准文件(Opcode编码 - 第295页)中定义。
该文件是公开的,可以从以下链接下载:
http://www.ecma-international.org/publications/standards/Ecma-335.htm
但是,操作码也在System.Reflection.Emit.OpCodes类中定义,它是mscorlib.dll类型的一部分。
在可用于从该类中提取相关信息的代码下方:
// Get the OpcCodes using Reflection
Type opCodes = typeof(OpCodes);
var opCodesList = opCodes.GetFields(BindingFlags.Public | BindingFlags.Static)
.Where(f => f.FieldType == typeof(OpCode))
.Select(f =>
{ OpCode opCode = (OpCode)f.GetValue(null);
return new {Name=f.Name, Instruction = opCode.Name, Size = opCode.Size, OpCode = string.Format("0x{0:X2}", opCode.Value) };
});
// Print to the Console
var opCodesStrings = opCodesList
.Select( o => string.Format("{0,-10}{1,-15}{2,-10}{3,-10}", o.Name, o.Instruction, o.Size, o.OpCode))
.ToList();
opCodesStrings.Insert(0, string.Format("{0,-10}{1,-15}{2,-10}{3,-10}", "Name", "Instruction", "Size", "OpCode"));
opCodesStrings.Insert(1, string.Format("{0,-10}{1,-15}{2,-10}{3,-10}", "----", "-----------", "----", "------"));
opCodesStrings.ForEach(Console.WriteLine);
产生的输出的第一行是:
Name Instruction Size OpCode ---- ----------- ---- ------ Nop nop 1 0x00 Break break 1 0x01 Ldarg_0 ldarg.0 1 0x02 Ldarg_1 ldarg.1 1 0x03 Ldarg_2 ldarg.2 1 0x04 Ldarg_3 ldarg.3 1 0x05 Ldloc_0 ldloc.0 1 0x06 Ldloc_1 ldloc.1 1 0x07 Ldloc_2 ldloc.2 1 0x08 Ldloc_3 ldloc.3 1 0x09 Stloc_0 stloc.0 1 0x0A Stloc_1 stloc.1 1 0x0B Stloc_2 stloc.2 1 0x0C Stloc_3 stloc.3 1 0x0D Ldarg_S ldarg.s 1 0x0E Ldarga_S ldarga.s 1 0x0F ...
以下链接指向描述每个OpCode的MSDN页面: https://msdn.microsoft.com/it-it/library/System.Reflection.Emit.OpCodes(v=vs.110).aspx