コード例 #1
0
ファイル: Disassembler.cs プロジェクト: soywiz/DotX86
 public string Disassemble(Instruction Instruction)
 {
     switch (Instruction.Type)
     {
         case InstructionType.Empty: return String.Format("{0}", Instruction.Opcode);
         case InstructionType.Register: return String.Format("{0} {1}", Instruction.Opcode, (ERegister)Instruction.Register1);
         case InstructionType.Value: return String.Format("{0} {1}", Instruction.Opcode, (int)Instruction.Value);
         case InstructionType.Indirect: return String.Format("{0} [0x{1:X}]", Instruction.Opcode, Instruction.Value);
         case InstructionType.RegisterRegister: return String.Format("{0} {1}, {2}", Instruction.Opcode, (ERegister)Instruction.Register1, (ERegister)Instruction.Register2);
         case InstructionType.RegisterValue: return String.Format("{0} {1}, {2}", Instruction.Opcode, (ERegister)Instruction.Register1, Instruction.Value);
         case InstructionType.RegisterOffsetRegister: return String.Format("{0} [{1}+{2}], {3}", Instruction.Opcode, (ERegister)Instruction.Register1, (int)Instruction.Value, (ERegister)Instruction.Register2);
         case InstructionType.RegisterRegisterOffset: return String.Format("{0} {1}, [{2}+{3}]", Instruction.Opcode, (ERegister)Instruction.Register1, (ERegister)Instruction.Register2, (int)Instruction.Value);
         default: throw(new Exception("Not implemented " + Instruction.Type));
     }
 }
コード例 #2
0
ファイル: MethodGenerator.cs プロジェクト: soywiz/DotX86
            private bool EmitInstruction(uint PC, uint nPC, Instruction Instruction, ILGenerator ILGenerator)
            {
                switch (Instruction.Opcode)
                {
                    case Opcode.PUSH:
                        {
                            LoadThreadContext();
                            LoadRegisterValue(Instruction.Register1);
                            CallFunction((Action<ThreadContext, uint>)Operations.PUSH_DWORD);
                        }
                        break;
                    case Opcode.MOV:
                        //Console.WriteLine("     {0}", Instruction.Type);
                        switch (Instruction.Type)
                        {
                            case InstructionType.RegisterValue:
                                LoadRegisterAddress(Instruction.Register1);
                                LoadValue(Instruction.Value);
                                CallFunction((REF_DWORD_DELEGATE)Operations.MOV_DWORD);
                                break;
                            case InstructionType.RegisterRegister:
                                LoadRegisterAddress(Instruction.Register1);
                                LoadRegisterValue(Instruction.Register2);
                                CallFunction((REF_DWORD_DELEGATE)Operations.MOV_DWORD);
                                break;
                            case InstructionType.RegisterOffsetRegister:
                                LoadThreadContext();

                                LoadRegisterValue(Instruction.Register1);
                                LoadValue(Instruction.Value);
                                ILGenerator.Emit(OpCodes.Add);

                                LoadRegisterValue(Instruction.Register2);

                                CallFunction((Action<ThreadContext, uint, uint>)Operations.STORE_DWORD);
                                break;
                            case InstructionType.RegisterRegisterOffset:
                                LoadThreadContext();

                                LoadRegisterAddress(Instruction.Register1);

                                LoadRegisterValue(Instruction.Register2);
                                LoadValue(Instruction.Value);
                                ILGenerator.Emit(OpCodes.Add);

                                CallFunction((TCTX_REF_DWORD_DELEGATE)Operations.LOAD_DWORD);
                                break;
                            default:
                                throw(new NotImplementedException());
                        }

                        break;
                    case Opcode.LEA:
                        switch (Instruction.Type)
                        {
                            // LEA REG, [REG + OFF]
                            case InstructionType.RegisterRegisterOffset:
                                LoadRegisterAddress(Instruction.Register1);
                                LoadRegisterValue(Instruction.Register2);
                                LoadValue(Instruction.Value);
                                ILGenerator.Emit(OpCodes.Add);

                                CallFunction((REF_DWORD_DELEGATE)Operations.MOV_DWORD);
                                break;
                            default:
                                throw (new NotImplementedException());
                        }
                        break;
                    case Opcode.SUB:
                        {
                            switch (Instruction.Type)
                            {
                                case InstructionType.RegisterValue:
                                    LoadRegisterAddress(Instruction.Register1);
                                    LoadValue(Instruction.Value);
                                    CallFunction((REF_DWORD_DELEGATE)Operations.SUB_DWORD);
                                    break;
                                default:
                                    throw (new NotImplementedException());
                            }
                        }
                        break;
                    case Opcode.ADD:
                        {
                            switch (Instruction.Type)
                            {
                                case InstructionType.RegisterValue:
                                    LoadRegisterAddress(Instruction.Register1);
                                    LoadValue(Instruction.Value);
                                    CallFunction((REF_DWORD_DELEGATE)Operations.ADD_DWORD);
                                    break;
                                case InstructionType.RegisterRegister:
                                    LoadRegisterAddress(Instruction.Register1);
                                    LoadRegisterValue(Instruction.Register2);
                                    CallFunction((REF_DWORD_DELEGATE)Operations.ADD_DWORD);
                                    break;
                                default:
                                    throw (new NotImplementedException());
                            }
                        }
                        break;
                    case Opcode.SHL:
                        {
                            switch (Instruction.Type)
                            {
                                case InstructionType.RegisterValue:
                                    LoadRegisterAddress(Instruction.Register1);
                                    LoadValue(Instruction.Value);
                                    CallFunction((REF_DWORD_DELEGATE)Operations.SHL_DWORD);
                                    break;
                                case InstructionType.RegisterRegister:
                                    LoadRegisterAddress(Instruction.Register1);
                                    LoadRegisterValue(Instruction.Register2);
                                    CallFunction((REF_DWORD_DELEGATE)Operations.SHL_DWORD);
                                    break;
                                default:
                                    throw(new NotImplementedException());
                            }
                        }
                        break;
                    case Opcode.TEST:
                        {
                            switch (Instruction.Type)
                            {
                                case InstructionType.RegisterRegister:
                                    LoadThreadContext();
                                    LoadRegisterValue(Instruction.Register1);
                                    LoadRegisterValue(Instruction.Register2);
                                    CallFunction((Action<ThreadContext, int, int>)Operations.TEST_DWORD);
                                    break;
                                default:
                                    throw (new NotImplementedException());
                            }
                        }
                        break;
                    case Opcode.CMP:
                        {
                            switch (Instruction.Type)
                            {
                                case InstructionType.RegisterValue:
                                    LoadThreadContext();
                                    LoadRegisterValue(Instruction.Register1);
                                    LoadValue(Instruction.Value);
                                    CallFunction((Action<ThreadContext, int, int>)Operations.CMP_DWORD);
                                    break;
                                default:
                                    throw (new NotImplementedException());
                            }
                        }
                        break;
                    case Opcode.XCHG:
                        if (Instruction.Register1 != Instruction.Register2)
                        {
                            LoadRegisterAddress(Instruction.Register1);
                            LoadRegisterAddress(Instruction.Register2);
                            CallFunction((REF_REF_DELEGATE)Operations.XCHG_DWORD);
                        }
                        break;
                    case Opcode.RETN:
                        {
                            LoadThreadContext();
                            CallFunction((Action<ThreadContext>)Operations.RETURN);

                            return false;
                        }
                    case Opcode.JZ:
                    case Opcode.JNZ:
                    case Opcode.JGE:
                        {
                            switch (Instruction.Type)
                            {
                                case InstructionType.Value:
                                    LoadThreadContext();
                                    LoadValue((uint)(nPC));
                                    LoadValue((uint)(nPC + Instruction.Value));
                                    switch (Instruction.Opcode)
                                    {
                                        case Opcode.JZ: CallFunction((Action<ThreadContext, uint, uint>)Operations.JUMP_ZERO); break;
                                        case Opcode.JNZ: CallFunction((Action<ThreadContext, uint, uint>)Operations.JUMP_NOT_ZERO); break;
                                        case Opcode.JGE: CallFunction((Action<ThreadContext, uint, uint>)Operations.JUMP_GREATER_EQUAL); break;
                                        default: throw (new NotImplementedException());
                                    }

                                    break;
                                default:
                                    throw (new NotImplementedException());
                            }
                            return false;
                        }
                    // idiv — Integer Division
                    // The idiv instruction divides the contents of the 64 bit integer EDX:EAX
                    // (constructed by viewing EDX as the most significant four bytes and EAX as
                    // the least significant four bytes) by the specified operand value. The quotient
                    // result of the division is stored into EAX, while the remainder is placed in EDX.
                    case Opcode.IDIV:
                        {
                            LoadThreadContext();
                            CallFunction((Action<ThreadContext>)Operations.IDIV);
                        }
                        break;
                    case Opcode.CDQ:
                        {
                            LoadThreadContext();
                            CallFunction((Action<ThreadContext>)Operations.CONVERT_DWORD_TO_QWORD);
                        }
                        break;
                    case Opcode.JMP:
                        {
                            switch (Instruction.Type)
                            {
                                case InstructionType.Indirect:
                                    LoadThreadContext();
                                    LoadValue((uint)Instruction.Value);
                                    CallFunction((Action<ThreadContext, uint>)Operations.JUMP_INDIRECT);
                                    break;
                                case InstructionType.Value:
                                    LoadThreadContext();
                                    LoadValue((uint)(nPC + Instruction.Value));
                                    CallFunction((Action<ThreadContext, uint>)Operations.JUMP);
                                    break;
                                default:
                                    throw(new NotImplementedException());
                            }
                            return false;
                        }
                    case Opcode.INT:
                        {
                            LoadThreadContext();
                            LoadValue(nPC);
                            LoadValue(Instruction.Value);
                            CallFunction((Action<ThreadContext, uint, uint>)Operations.INTERRUPT);
                            return false;
                        }
                    case Opcode.LEAVE:
                        {
                            LoadThreadContext();
                            CallFunction((Action<ThreadContext>)Operations.LEAVE);
                            //throw(new NotImplementedException());
                        }
                        break;
                    case Opcode.CALL:
                        {
                            uint ReturnPC = nPC;
                            uint CallPC = ReturnPC + Instruction.Value;

                            LoadThreadContext();
                            LoadValue((uint)ReturnPC);
                            LoadValue((uint)CallPC);
                            CallFunction((Action<ThreadContext, uint, uint>)Operations.CALL);
                            return false;

                            /*
                            int AllocatedIndex = 0;

                            Console.WriteLine("CALL: {0:X}, {1:X}, {2:X}", CallPC, PC, Instruction.Value);

                            Action<uint, int, Instruction> Context = (ContextCallPC, ContextAllocatedIndex, ContextInstruction) =>
                            {
                                CpuContext.MethodCache[ContextAllocatedIndex] = (ThreadState) =>
                                {
                                    Console.WriteLine("Generating method : {0} : {1:X}", ContextInstruction, ContextCallPC);
                                    var Method = CpuContext.GenerateMethod(ContextCallPC);
                                    CpuContext.MethodCache[ContextAllocatedIndex] = Method;
                                    Method(ThreadState);
                                };
                            };
                            Context(CallPC, AllocatedIndex, Instruction);

                            LoadThreadContext();
                            LoadValue((uint)AllocatedIndex);
                            //CallTailFunction((Action<ThreadContext, int>)Operations.CALL_INDEX);
                            CallFunction((Action<ThreadContext, int>)Operations.CALL_INDEX);
                            ILGenerator.Emit(OpCodes.Ret);
                            */

                            /*
                            LoadThreadContext();
                            LoadThreadContext();
                            ILGenerator.Emit(OpCodes.Ldfld, typeof(ThreadContext).GetField("TestMethod"));
                            //ILGenerator.Emit(OpCodes.Callvirt, typeof(Action<ThreadContext>).GetMethod("Invoke"));
                            CallFunction((Action<ThreadContext, Action<ThreadContext>>)Operations.CALLVIRT);
                            */

                        }
                    default:
                        throw (new NotImplementedException("Unimplemented opcode " + Instruction.Opcode));
                }
                return true;
            }