Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 153 стр.

UptoLike

}
}
#endregion
}
public class CilCodec
{
public static Instruction[] DecodeCil(byte[] cilStream)
{
int offset = 0;
ArrayList instructions = new ArrayList();
while (offset < cilStream.Length)
{
OpCode code;
short s2 = cilStream[offset];
if (s2 == 0xFE)
{
byte s1 = cilStream[offset+1];
code = (OpCode)(codes[((s2 << 8) | s1)]);
}
else
code = (OpCode)(codes[s2]);
Instruction ins = new Instruction(code,offset);
offset += code.Size;
switch (code.OperandType)
{
case OperandType.InlineNone: /* None */
break;
case OperandType.ShortInlineBrTarget: /* int8 */
ins.Operand = offset + 1 +
(sbyte)cilStream[offset];
offset++;
break;
case OperandType.InlineI: /* int32 */
ins.Operand = BitConverter.ToInt32(cilStream,offset);
offset += 4;
Исходный код программы CilCodec
293
private object operand;
private int offset;
private string formatOperand()
{
string s;
switch (code.OperandType)
{
case OperandType.InlineNone: /* None */
return “”;
case OperandType.ShortInlineBrTarget: /* int8 */
case OperandType.InlineBrTarget: /* int32 */
return String.Format(“IL_{0:X8}”,operand);
case OperandType.InlineI: /* int32 */
return String.Format(“0x{0:X8}”,operand);
case OperandType.InlineI8: /* int64 */
return String.Format(“0x{0:X16}”,operand);
case OperandType.ShortInlineI: /* int8 */
return String.Format(“0x{0:X2}”,operand);
case OperandType.ShortInlineVar: /* unsigned int8 */
case OperandType.InlineVar: /* unsigned int16 */
return String.Format(“{0:d}”,operand);
case OperandType.ShortInlineR: /* float32 */
case OperandType.InlineR: /* float64 */
return String.Format(“{0:e}”,operand);
case OperandType.InlineSwitch: /* switch */
s = “(“;
foreach (int target in (int[])operand)
s += String.Format(“IL_{0:X8}”,target) + “ “;
return s + “)”;
default: /* token */
s = String.Format(“{0:X8}”,operand);
return “(“+s.Substring(0,2)+”)”+s.Substring(2);
292
CIL и системное программирование в Microsoft .NET
292                        CIL и системное программирование в Microsoft .NET   Исходный код программы CilCodec                                         293


      private object operand;                                                               }
      private int offset;                                                               }

      private string formatOperand()                                                    #endregion
      {                                                                             }
         string s;
                                                                                    public class CilCodec
        switch (code.OperandType)                                                   {
        {                                                                             public static Instruction[] DecodeCil(byte[] cilStream)
           case OperandType.InlineNone: /* None */                                    {
              return “”;                                                                 int offset = 0;
                                                                                         ArrayList instructions = new ArrayList();
           case OperandType.ShortInlineBrTarget: /* int8 */
           case OperandType.InlineBrTarget: /* int32 */                                     while (offset < cilStream.Length)
              return String.Format(“IL_{0:X8}”,operand);                                    {
                                                                                               OpCode code;
           case OperandType.InlineI: /* int32 */                                               short s2 = cilStream[offset];
              return String.Format(“0x{0:X8}”,operand);                                        if (s2 == 0xFE)
                                                                                               {
           case OperandType.InlineI8: /* int64 */                                                 byte s1 = cilStream[offset+1];
              return String.Format(“0x{0:X16}”,operand);                                          code = (OpCode)(codes[((s2 << 8) | s1)]);
                                                                                               }
           case OperandType.ShortInlineI: /* int8 */                                           else
              return String.Format(“0x{0:X2}”,operand);                                           code = (OpCode)(codes[s2]);

           case OperandType.ShortInlineVar: /* unsigned int8 */                                 Instruction ins = new Instruction(code,offset);
           case OperandType.InlineVar: /* unsigned int16 */                                     offset += code.Size;
              return String.Format(“{0:d}”,operand);
                                                                                                switch (code.OperandType)
           case OperandType.ShortInlineR: /* float32 */                                         {
           case OperandType.InlineR: /* float64 */                                                 case OperandType.InlineNone: /* None */
              return String.Format(“{0:e}”,operand);                                                  break;

           case OperandType.InlineSwitch: /* switch */                                            case OperandType.ShortInlineBrTarget: /* int8 */
              s = “(“;                                                                               ins.Operand = offset + 1 +
              foreach (int target in (int[])operand)                                                            (sbyte)cilStream[offset];
                 s += String.Format(“IL_{0:X8}”,target) + “ “;                                       offset++;
              return s + “)”;                                                                        break;

           default: /* token */                                                                   case OperandType.InlineI: /* int32 */
              s = String.Format(“{0:X8}”,operand);                                                   ins.Operand = BitConverter.ToInt32(cilStream,offset);
              return “(“+s.Substring(0,2)+”)”+s.Substring(2);                                        offset += 4;