/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { if (ctx.Operand1 is ConstantOperand) { if (IsByte(ctx.Operand1)) emitter.Emit(CONST8, ctx.Operand1, null); else if (IsShort(ctx.Operand1) || IsChar(ctx.Operand1)) emitter.Emit(CONST16, ctx.Operand1, null); else if (IsInt(ctx.Operand1)) emitter.Emit(CONST32, ctx.Operand1, null); return; } if (ctx.Operand1 is RegisterOperand) { if ((ctx.Operand1 as RegisterOperand).Register is SegmentRegister) switch (((ctx.Operand1 as RegisterOperand).Register as SegmentRegister).Segment) { case SegmentRegister.SegmentType.CS: emitter.Emit(PUSH_CS, null, null); return; case SegmentRegister.SegmentType.SS: emitter.Emit(PUSH_SS, null, null); return; case SegmentRegister.SegmentType.DS: emitter.Emit(PUSH_DS, null, null); return; case SegmentRegister.SegmentType.ES: emitter.Emit(PUSH_ES, null, null); return; case SegmentRegister.SegmentType.FS: emitter.Emit(PUSH_FS, null, null); return; case SegmentRegister.SegmentType.GS: emitter.Emit(PUSH_GS, null, null); return; default: throw new InvalidOperationException(@"unable to emit opcode for segment register"); } } emitter.Emit(PUSH, ctx.Operand1, null, null); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { if (ctx.Result is RegisterOperand) emitter.WriteByte ((byte)(0x58 + (ctx.Result as RegisterOperand).Register.RegisterCode)); else emitter.Emit (POP.Code, 0, ctx.Result, null); }
private void HandleMemoryToMemoryOperation(Context ctx, Operand register, bool useStack) { Operand destination = ctx.Result; Operand source = ctx.Operand1; Debug.Assert (destination is MemoryOperand && source is MemoryOperand); if (register == null) register = new RegisterOperand (destination.Type, GeneralPurposeRegister.EDX); ctx.Operand1 = register; Context before = ctx.InsertBefore (); if (useStack) { before.SetInstruction (CPUx86.Instruction.PushInstruction, null, register); before.AppendInstruction (CPUx86.Instruction.MovInstruction, register, source); } else before.SetInstruction (CPUx86.Instruction.MovInstruction, register, source); if (useStack) ctx.AppendInstruction (CPUx86.Instruction.PopInstruction, register); }
/// <summary> /// /// </summary> /// <param name="ctx"></param> /// <param name="emitter"></param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { RegisterOperand rop = (RegisterOperand)ctx.Result; MemoryOperand mop = (MemoryOperand)ctx.Operand1; byte[] code; if (null != mop.Base) { code = new byte[] { 0x8d, 0x84, (4 << 3) }; code[1] |= (byte)((rop.Register.RegisterCode & 0x7)); code[2] |= (byte)((mop.Base.RegisterCode & 0x7)); } else { code = new byte[] { 0xb8 }; } emitter.Write (code, 0, code.Length); emitter.EmitImmediate (mop); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { if (ctx.Operand1 is RegisterOperand) emitter.Emit(JmpReg, ctx.Operand1); else emitter.EmitBranch(JMP, ctx.Branch.Targets[0]); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { OpCode opcode; switch (ctx.ConditionCode) { case IR.ConditionCode.Equal: opcode = E; break; case IR.ConditionCode.LessThan: opcode = LT; break; case IR.ConditionCode.LessOrEqual: opcode = LE; break; case IR.ConditionCode.GreaterOrEqual: opcode = GE; break; case IR.ConditionCode.GreaterThan: opcode = GT; break; case IR.ConditionCode.NotEqual: opcode = NE; break; case IR.ConditionCode.UnsignedGreaterOrEqual: opcode = UGE; break; case IR.ConditionCode.UnsignedGreaterThan: opcode = UGT; break; case IR.ConditionCode.UnsignedLessOrEqual: opcode = ULE; break; case IR.ConditionCode.UnsignedLessThan: opcode = ULT; break; case IR.ConditionCode.Parity: opcode = P; break; case IR.ConditionCode.NoParity: opcode = NP; break; case IR.ConditionCode.NoCarry: opcode = NC; break; case IR.ConditionCode.Carry: opcode = C; break; case IR.ConditionCode.Zero: opcode = Z; break; case IR.ConditionCode.NoZero: opcode = NZ; break; default: throw new NotSupportedException(); } emitter.Emit(opcode, ctx.Result, null); }
/// <summary> /// Creates the ISR methods. /// </summary> /// <param name="compiler">The compiler.</param> private void CreateISRMethods(AssemblyCompiler compiler) { // Create Interrupt Service Routines (ISR) RuntimeMethod InterruptMethod = compiler.Assembly.EntryPoint; // TODO: replace with another entry point SigType I1 = new SigType(CilElementType.I1); SigType I4 = new SigType(CilElementType.I4); RegisterOperand eax = new RegisterOperand(I4, GeneralPurposeRegister.EAX); for (int i = 0; i <= 256; i++) { InstructionSet set = new InstructionSet(100); Context ctx = new Context(set, -1); ctx.SetInstruction(CPUx86.Instruction.CliInstruction); if ((i != 8) && (i < 10 || i > 14)) // For IRQ 8, 10, 11, 12, 13, 14 the cpu automatically pushed the error code ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I4, 0x0)); ctx.AppendInstruction(CPUx86.Instruction.PushadInstruction); ctx.AppendInstruction(CPUx86.Instruction.PushInstruction, null, new ConstantOperand(I4, i)); // TODO: Set method parameters ctx.AppendInstruction(CPUx86.Instruction.CallInstruction, InterruptMethod); ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, eax); ctx.AppendInstruction(CPUx86.Instruction.PopadInstruction); ctx.AppendInstruction(CPUx86.Instruction.PopInstruction, eax); ctx.AppendInstruction(CPUx86.Instruction.StiInstruction); //ctx.AppendInstruction(CPUx86.Instruction.IRetdInstruction); CompilerGeneratedMethod method = LinkTimeCodeGenerator.Compile(compiler, @"InterruptISR" + i.ToString(), set); } }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> public virtual void Run() { for (int index = 0; index < BasicBlocks.Count; index++) for (Context ctx = new Context (InstructionSet, BasicBlocks[index]); !ctx.EndOfInstruction; ctx.GotoNext ()) if (ctx.Instruction != null) ctx.Clone ().Visit (this); }
/// <summary> /// Performs stage specific processing on the compiler context. /// </summary> public void Run() { // Create the prologue block Context ctx = new Context(InstructionSet, -1); // Add a jump instruction to the first block from the prologue ctx.AppendInstruction(IR.Instruction.JmpInstruction); //ctx.AppendInstruction(CIL.Instruction.Get(CIL.OpCode.Br)); ctx.SetBranch(0); ctx.Label = -1; _prologue = CreateBlock(-1, ctx.Index); SplitIntoBlocks(0); // Create the epilogue block ctx = new Context(InstructionSet, -1); // Add null instruction, necessary to generate a block index ctx.AppendInstruction(null); ctx.Ignore = true; ctx.Label = Int32.MaxValue; _epilogue = CreateBlock(Int32.MaxValue, ctx.Index); // Link all the blocks together BuildBlockLinks(_prologue); // Link Exception Header Clauses LinkExceptionHeaderClauses(); }
/// <summary> /// /// </summary> /// <param name="ctx"></param> /// <param name="emitter"></param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { emitter.Emit (new OpCode (new byte[] { 0xf, 0xa2 }), null, null); }
/// <summary> /// Initializes a new instance of the <see cref="TypeInitializerSchedulerStage"/> class. /// </summary> public TypeInitializerSchedulerStage() { InstructionSet = new InstructionSet(1024); _ctx = CreateContext(-1); _ctx.AppendInstruction(IR.Instruction.PrologueInstruction); _ctx.Other = 0; // stacksize }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> public void ReplaceIntrinsicCall(Context context) { Operand operand1 = context.Operand1; RegisterOperand imm = new RegisterOperand(new SigType(CilElementType.U4), GeneralPurposeRegister.EAX); context.SetInstruction(IR.Instruction.MoveInstruction, imm, operand1); context.AppendInstruction(IR.Instruction.MoveInstruction, new RegisterOperand(new SigType(CilElementType.U4), _control), imm); }
/// <summary> /// Visitation function for <see cref="IR.IIRVisitor.AddressOfInstruction"/> instruction. /// </summary> /// <param name="ctx">The context.</param> void IR.IIRVisitor.AddressOfInstruction(Context ctx) { Operand opRes = ctx.Result; RegisterOperand eax = new RegisterOperand (opRes.Type, GeneralPurposeRegister.EAX); ctx.Result = eax; ctx.ReplaceInstructionOnly (CPUx86.Instruction.LeaInstruction); // ctx.Ignore = true; ctx.AppendInstruction (CPUx86.Instruction.MovInstruction, opRes, eax); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem) { Operand result = context.Result; RegisterOperand imm = new RegisterOperand(new SigType(CilElementType.U4), GeneralPurposeRegister.EAX); context.SetInstruction(IR.Instruction.MoveInstruction, imm, new RegisterOperand(new SigType(CilElementType.U4), _control)); context.AppendInstruction(IR.Instruction.MoveInstruction, result, imm); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { emitter.WriteByte(0xE8); emitter.WriteByte(0x00); emitter.WriteByte(0x00); emitter.WriteByte(0x00); emitter.WriteByte(0x00); emitter.Call(ctx.InvokeTarget); }
/// <summary> /// Visitation function for <see cref="CIL.ICILVisitor.Add"/>. /// </summary> /// <param name="ctx">The context.</param> void CIL.ICILVisitor.Add(Context ctx) { if (ctx.Operand1.StackType == StackTypeCode.F) { HandleCommutativeOperation(ctx, CPUx86.Instruction.SseAddInstruction); ExtendToR8(ctx); } else HandleCommutativeOperation(ctx, CPUx86.Instruction.AddInstruction); }
/// <summary> /// Emits the specified platform instruction. /// </summary> /// <param name="ctx">The context.</param> /// <param name="emitter">The emitter.</param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { switch (ctx.ConditionCode) { case IR.ConditionCode.Equal: emitter.EmitBranch(JE, ctx.Branch.Targets[0]); break; case IR.ConditionCode.GreaterOrEqual: emitter.EmitBranch(JGE, ctx.Branch.Targets[0]); break; case IR.ConditionCode.GreaterThan: emitter.EmitBranch(JG, ctx.Branch.Targets[0]); break; case IR.ConditionCode.LessOrEqual: emitter.EmitBranch(JLE, ctx.Branch.Targets[0]); break; case IR.ConditionCode.LessThan: emitter.EmitBranch(JL, ctx.Branch.Targets[0]); break; case IR.ConditionCode.NotEqual: emitter.EmitBranch(JNE, ctx.Branch.Targets[0]); break; case IR.ConditionCode.UnsignedGreaterOrEqual: emitter.EmitBranch(JAE, ctx.Branch.Targets[0]); break; case IR.ConditionCode.UnsignedGreaterThan: emitter.EmitBranch(JA, ctx.Branch.Targets[0]); break; case IR.ConditionCode.UnsignedLessOrEqual: emitter.EmitBranch(JBE, ctx.Branch.Targets[0]); break; case IR.ConditionCode.UnsignedLessThan: emitter.EmitBranch(JB, ctx.Branch.Targets[0]); break; case IR.ConditionCode.NotSigned: emitter.EmitBranch(JNS, ctx.Branch.Targets[0]); break; case IR.ConditionCode.Signed: emitter.EmitBranch(JS, ctx.Branch.Targets[0]); break; default: throw new NotSupportedException(); } }
/// <summary> /// Converts the given instruction from three address format to a two address format. /// </summary> /// <param name="ctx">The conversion context.</param> private static void ThreeTwoAddressConversion(Context ctx) { Operand result = ctx.Result; Operand op1 = ctx.Operand1; Operand op2 = ctx.Operand2; if (ctx.Instruction is IR.FloatingPointCompareInstruction) return; if (ctx.Instruction is CIL.MulInstruction) { if (!(op1 is ConstantOperand) && (op2 is ConstantOperand)) { Operand temp = op1; op1 = op2; op2 = temp; } } RegisterOperand eax = new RegisterOperand (op1.Type, op1.StackType == StackTypeCode.F ? (Register)SSE2Register.XMM0 : GeneralPurposeRegister.EAX); RegisterOperand storeOperand = new RegisterOperand (result.Type, result.StackType == StackTypeCode.F ? (Register)SSE2Register.XMM0 : GeneralPurposeRegister.EAX); ctx.Result = storeOperand; ctx.Operand1 = op2; ctx.Operand2 = null; ctx.OperandCount = 1; if (op1.StackType != StackTypeCode.F) { if (IsSigned (op1) && !(op1 is ConstantOperand)) ctx.InsertBefore ().SetInstruction (IR.Instruction.SignExtendedMoveInstruction, eax, op1); else if (IsUnsigned (op1) && !(op1 is ConstantOperand)) ctx.InsertBefore ().SetInstruction (IR.Instruction.ZeroExtendedMoveInstruction, eax, op1); else ctx.InsertBefore ().SetInstruction (CPUx86.Instruction.MovInstruction, eax, op1); } else { if (op1.Type.Type == CilElementType.R4) { if (op1 is ConstantOperand) { Context before = ctx.InsertBefore (); before.SetInstruction (CPUx86.Instruction.MovInstruction, eax, op1); before.AppendInstruction (CPUx86.Instruction.Cvtss2sdInstruction, eax, eax); } else ctx.InsertBefore ().SetInstruction (CPUx86.Instruction.Cvtss2sdInstruction, eax, op1); } else ctx.InsertBefore ().SetInstruction (CPUx86.Instruction.MovInstruction, eax, op1); } ctx.AppendInstruction (CPUx86.Instruction.MovInstruction, result, eax); }
private bool CheckAssignmentForCompliance(Context allocation, Context assignment) { // Only direct assignment without any casts is compliant. We can't perform casts or anything alike here, // as that is hard to complete at this point of time. RuntimeType allocationType = allocation.InvokeTarget.DeclaringType; RuntimeType storageType = assignment.RuntimeField.Type; return ReferenceEquals(allocationType, storageType); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem) { Operand result = context.Result; RegisterOperand tmp = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.Ptr), GeneralPurposeRegister.EDX); MemoryOperand operand = new MemoryOperand(context.Operand1.Type, GeneralPurposeRegister.EDX, new System.IntPtr(0)); context.SetInstruction(CPUx86.Instruction.MovInstruction, tmp, context.Operand1); context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, operand); }
/// <summary> /// Creates the operand. /// </summary> /// <param name="ctx">The CTX.</param> /// <returns></returns> public Operand CreateOperand(Context ctx) { /* HACK: * Position independent code on x86 requires EIP relative addressing, which * unfortunately isn't available. We try to work around this limitation by * storing the EIP of the first instruction on the stack, however this isn't * enough. So PIC with Literals doesn't work for now. */ //return new LabelOperand(this.Type, GeneralPurposeRegister.EBP, -8, this.Label); return new LabelOperand (ctx.LiteralData.Type, null, 0, ctx.LiteralData.Label); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem) { SigType I4 = new SigType(CilElementType.I4); RegisterOperand esp = new RegisterOperand(I4, GeneralPurposeRegister.ESP); context.SetInstruction(CPUx86.Instruction.MovInstruction, esp, context.Operand1); context.AppendInstruction(CPUx86.Instruction.PopadInstruction); context.AppendInstruction(CPUx86.Instruction.AddInstruction, esp, new ConstantOperand(I4, 0x08)); context.AppendInstruction(CPUx86.Instruction.StiInstruction); context.AppendInstruction(CPUx86.Instruction.IRetdInstruction); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> public void ReplaceIntrinsicCall(Context context) { Operand result = context.Result; Operand operand = context.Operand1; RegisterOperand eax = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I4), GeneralPurposeRegister.EAX); RegisterOperand ecx = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I4), GeneralPurposeRegister.ECX); RegisterOperand reg = new RegisterOperand(new Mosa.Runtime.Metadata.Signatures.SigType(Mosa.Runtime.Metadata.CilElementType.I4), GeneralPurposeRegister.EBX); context.SetInstruction(CPUx86.Instruction.MovInstruction, eax, operand); context.AppendInstruction(CPUx86.Instruction.XorInstruction, ecx, ecx); context.AppendInstruction(CPUx86.Instruction.CpuIdEbxInstruction); context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, reg); }
/// <summary> /// /// </summary> /// <param name="ctx"></param> /// <param name="emitter"></param> protected override void Emit(Context ctx, MachineCodeEmitter emitter) { OpCode opCode = ComputeOpCode(ctx.Result, ctx.Operand1, ctx.Operand2); if (ctx.Operand1 is ConstantOperand) { ConstantOperand op = ctx.Operand1 as ConstantOperand; op = new ConstantOperand(new Mosa.Runtime.Metadata.Signatures.SigType(CilElementType.U1), op.Value); emitter.Emit(opCode, ctx.Result, op); } else emitter.Emit(opCode, ctx.Operand1, null); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem) { Operand result = context.Result; SigType u4 = new SigType(CilElementType.U4); RegisterOperand eax = new RegisterOperand(u4, GeneralPurposeRegister.EAX); context.SetInstruction(CPUx86.Instruction.PopInstruction, eax); context.AppendInstruction(CPUx86.Instruction.AddInstruction, eax, new RegisterOperand(u4, GeneralPurposeRegister.ESP)); context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(0))); context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, eax); context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, eax); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> public void ReplaceIntrinsicCall(Context context) { Operand operand1 = context.Operand1; Operand operand2 = context.Operand2; RegisterOperand edx = new RegisterOperand (operand1.Type, GeneralPurposeRegister.EDX); RegisterOperand eax = new RegisterOperand (operand2.Type, GeneralPurposeRegister.EAX); context.SetInstruction (CPUx86.Instruction.MovInstruction, edx, operand1); context.AppendInstruction (CPUx86.Instruction.MovInstruction, eax, operand2); context.AppendInstruction (CPUx86.Instruction.OutInstruction, null, edx, eax); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem) { Operand result = context.Result; Operand operand1 = context.Operand1; RegisterOperand edx = new RegisterOperand(operand1.Type, GeneralPurposeRegister.EDX); RegisterOperand eax = new RegisterOperand(result.Type, GeneralPurposeRegister.EAX); context.SetInstruction(CPUx86.Instruction.MovInstruction, edx, operand1); context.AppendInstruction(CPUx86.Instruction.InInstruction, eax, edx); context.AppendInstruction(CPUx86.Instruction.MovInstruction, result, eax); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem) { Operand dest = context.Operand1; Operand value = context.Operand2; RegisterOperand edx = new RegisterOperand(dest.Type, GeneralPurposeRegister.EDX); RegisterOperand eax = new RegisterOperand(value.Type, GeneralPurposeRegister.EAX); MemoryOperand memory = new MemoryOperand(new SigType(context.InvokeTarget.Signature.Parameters[1].Type), GeneralPurposeRegister.EDX, new IntPtr(0)); context.SetInstruction(CPUx86.Instruction.MovInstruction, edx, dest); context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, value); context.AppendInstruction(CPUx86.Instruction.MovInstruction, memory, eax); }
/// <summary> /// Replaces the instrinsic call site /// </summary> /// <param name="context">The context.</param> /// <param name="typeSystem">The type system.</param> public void ReplaceIntrinsicCall(Context context, ITypeSystem typeSystem) { SigType u4 = new SigType(Runtime.Metadata.CilElementType.U4); RegisterOperand ebp = new RegisterOperand(u4, GeneralPurposeRegister.EBP); RegisterOperand esp = new RegisterOperand(u4, GeneralPurposeRegister.ESP); RegisterOperand eax = new RegisterOperand(u4, GeneralPurposeRegister.EAX); RegisterOperand ebx = new RegisterOperand(u4, GeneralPurposeRegister.EBX); RegisterOperand ecx = new RegisterOperand(u4, GeneralPurposeRegister.ECX); RegisterOperand edx = new RegisterOperand(u4, GeneralPurposeRegister.EDX); RegisterOperand esi = new RegisterOperand(u4, GeneralPurposeRegister.ESI); RegisterOperand edi = new RegisterOperand(u4, GeneralPurposeRegister.EDI); context.SetInstruction(CPUx86.Instruction.PushInstruction, null, ebp); context.AppendInstruction(CPUx86.Instruction.MovInstruction, ebp, esp); context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, ebx); context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, esi); context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, edi); // Load register context context.AppendInstruction(CPUx86.Instruction.MovInstruction, eax, new MemoryOperand(u4, GeneralPurposeRegister.ESP, new IntPtr(28))); // Load exception handler context.AppendInstruction(CPUx86.Instruction.MovInstruction, ecx, new MemoryOperand(u4, GeneralPurposeRegister.ESP, new IntPtr(32))); // Save EBP context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, ebp); // Restore register values context.AppendInstruction(CPUx86.Instruction.MovInstruction, ebp, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(24))); context.AppendInstruction(CPUx86.Instruction.MovInstruction, ebx, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(4))); context.AppendInstruction(CPUx86.Instruction.MovInstruction, esi, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(16))); context.AppendInstruction(CPUx86.Instruction.MovInstruction, edi, new MemoryOperand(u4, GeneralPurposeRegister.EAX, new IntPtr(20))); // Align ESP context.AppendInstruction(CPUx86.Instruction.MovInstruction, edx, esp); context.AppendInstruction(CPUx86.Instruction.AndInstruction, esp, new ConstantOperand(u4, 0xFFFFFFF0u)); context.AppendInstruction(CPUx86.Instruction.SubInstruction, esp, new ConstantOperand(u4, 0x8u)); // Save original ESP context.AppendInstruction(CPUx86.Instruction.PushInstruction, null, edx); // Call catch handler context.AppendInstruction(CPUx86.Instruction.CallInstruction, ecx); // Restore registers context.AppendInstruction(CPUx86.Instruction.PopInstruction, esp); context.AppendInstruction(CPUx86.Instruction.PopInstruction, ebp); context.AppendInstruction(CPUx86.Instruction.PopInstruction, esi); context.AppendInstruction(CPUx86.Instruction.PopInstruction, edi); context.AppendInstruction(CPUx86.Instruction.PopInstruction, ebx); context.AppendInstruction(CPUx86.Instruction.LeaveInstruction); context.AppendInstruction(CPUx86.Instruction.RetInstruction); }
/// <summary> /// Create an empty block. /// </summary> /// <param name="label">The label.</param> /// <returns></returns> protected Context CreateEmptyBlockContext(int label) { Context ctx = new Context (InstructionSet, -1); BasicBlock block = CreateBlock (BasicBlocks.Count + 0x10000000); ctx.BasicBlock = block; // Need a dummy instruction at the start of each block to establish a starting point of the block ctx.AppendInstruction (null); ctx.Label = label; block.Index = ctx.Index; ctx.Ignore = true; return ctx; }