public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { XS.DisableInterrupts(); // bochs magic break //Exchange(BX, BX); XS.Halt(); }
/* * * public static unsafe void Fill16Blocks( * byte *dest, [ebp + 8] * int value, [ebp + 12] * int BlocksNum) [ebp + 16] */ public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { /* First we copy dest, value and DestSize from EBP (stack) to 3 different registers */ XS.Comment("Destination (int pointer)"); XS.Set(EAX, EBP, sourceDisplacement: DestDisplacement); XS.Comment("Value"); XS.Set(EBX, EBP, sourceDisplacement: ValueDisplacement); XS.Comment("BlocksNum"); XS.Set(ECX, EBP, sourceDisplacement: BlocksNumDisplacement); /* * Now we need to copy 'value' (EBX) to an SSE register but we should not simply do a copy (!) * but all the register with 'value' repeating! * That is in the 16 byte SSE register should go this repeating pattern: * |value|value|value|value * luckily we don't need to do a loop for this there is the SSE3 instruction for this shufps */ XS.SSE2.MoveD(XMM0, EBX); XS.SSE.Shufps(XMM0, XMM0, 0x0000); // This broadcast the first element of XMM0 on the other 3 /* Do the 'loop' */ XS.Xor(EDI, EDI); // EDI is 0 XS.Label(".loop"); //XS.SSE.MoveUPS(EAX, XMM0, destinationIsIndirect: true, destinationDisplacement: EDI); XS.LiteralCode("movups[EAX + EDI], XMM0"); XS.Add(EDI, 16); XS.Sub(ECX, 1); //XS.LiteralCode("jnz .loop"); XS.Jump(ConditionalTestEnum.NotZero, ".loop"); //XS.Return(); }
public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { // $this ebp+8 XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 8); XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceDisplacement: 8, sourceIsIndirect: true); // element count XS.Push(XSRegisters.EAX); }
public static void Assemble(Assembler.Assembler aAssembler, uint aElementSize, _MethodInfo aMethod, ILOpCode aOpCode, bool debugEnabled) { // stack == the new value // stack + 1 == the index // stack + 2 == the array DoNullReferenceCheck(aAssembler, debugEnabled, (int)(8 + Align(aElementSize, 4))); uint xStackSize = aElementSize; if (xStackSize % 4 != 0) { xStackSize += 4 - xStackSize % 4; } // calculate element offset into array memory (including header) XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: (int)xStackSize); // the index XS.Set(XSRegisters.EDX, aElementSize); XS.Multiply(XSRegisters.EDX); XS.Add(XSRegisters.EAX, ObjectUtilities.FieldDataOffset + 4); XS.Set(XSRegisters.EDX, XSRegisters.ESP, sourceDisplacement: (int)xStackSize + 8); // the array XS.Add(XSRegisters.EDX, XSRegisters.EAX); XS.Push(XSRegisters.EDX); XS.Pop(XSRegisters.ECX); for (int i = (int)(aElementSize / 4) - 1; i >= 0; i -= 1) { new Comment(aAssembler, "Start 1 dword"); XS.Pop(XSRegisters.EBX); XS.Set(XSRegisters.ECX, XSRegisters.EBX, destinationIsIndirect: true); XS.Add(XSRegisters.ECX, 4); } switch (aElementSize % 4) { case 1: { new Comment(aAssembler, "Start 1 byte"); XS.Pop(XSRegisters.EBX); XS.Set(XSRegisters.ECX, XSRegisters.BL, destinationIsIndirect: true); break; } case 2: { new Comment(aAssembler, "Start 1 word"); XS.Pop(XSRegisters.EBX); XS.Set(XSRegisters.ECX, XSRegisters.BX, destinationIsIndirect: true); break; } case 0: { break; } default: throw new Exception("Remainder size " + (aElementSize % 4) + " not supported!"); } XS.Add(XSRegisters.ESP, 12); }
/*public static void BlockCopy( * Array src, [ebp + 24] * int srcOffset, [ebp + 20] * Array dst, [ebp + 16] * int dstOffset, [ebp + 12] * int count); [ebp + 8] */ public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { new CPUx86.Mov { DestinationReg = CPUx86.Registers.ESI, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 24 }; new CPUx86.Add { DestinationReg = CPUx86.Registers.ESI, SourceValue = 16 }; new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 20 }; new CPUx86.Add { DestinationReg = CPUx86.Registers.ESI, SourceReg = CPUx86.Registers.EAX }; new CPUx86.Mov { DestinationReg = CPUx86.Registers.EDI, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 16 }; new CPUx86.Add { DestinationReg = CPUx86.Registers.EDI, SourceValue = 16 }; new CPUx86.Mov { DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 12 }; new CPUx86.Add { DestinationReg = CPUx86.Registers.EDI, SourceReg = CPUx86.Registers.EAX }; new CPUx86.Mov { DestinationReg = CPUx86.Registers.ECX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 8 }; new CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat }; }
public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { // $this ebp+8 XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 8); XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); new Push { DestinationIsIndirect = true, DestinationReg = RegistersEnum.EAX, DestinationDisplacement = 8 }; }
private void DoExecute(Assembler.Assembler assembler, MethodInfo aMethod, ILOpCode aOpCode, OpType aTargetType, bool debugEnabled) { new Comment(assembler, $"Type = {aTargetType.Value}"); if (aTargetType.Value.BaseType == typeof(ValueType)) { } else if (aTargetType.Value.BaseType == typeof(object)) { throw new NotImplementedException($"Constrained not implemented for {aTargetType.Value}"); } }
private static Cpu BuildCpu(List <IOperation> source, ulong programBase = 0) { var memory = new SystemMemory(200L); var machineCode = new Assembler.Assembler().Assemble(source); memory.WriteBlock(machineCode, programBase); var cpu = new Cpu(memory); return(cpu); }
public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { // $this ebp+8 new Mov { DestinationReg = Registers.EAX, SourceReg = Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 8 }; new Mov { DestinationReg = Registers.EAX, SourceReg = Registers.EAX, SourceIsIndirect = true }; new Push { DestinationIsIndirect = true, DestinationReg = Registers.EAX, DestinationDisplacement = 8 }; }
public MainForm() { InitializeComponent(); _computer = new Computer(); _computer.Reset(); var assembler = new Assembler.Assembler(); assembler.ReadAssemFile("test_video.asm"); assembler.AssembleCode(); assembler.SaveHexFile("test_video.hex"); _computer.ComputerMemory.LoadMachineCodeFromFile("test_video.hex"); }
/*public static void BlockCopy( * Array src, [ebp + 24] * int srcOffset, [ebp + 20] * Array dst, [ebp + 16] * int dstOffset, [ebp + 12] * int count); [ebp + 8] */ public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { XS.Set(XSRegisters.ESI, XSRegisters.EBP, sourceDisplacement: 24); XS.Add(XSRegisters.ESI, 16); XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 20); XS.Add(XSRegisters.ESI, XSRegisters.EAX); XS.Set(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: 16); XS.Add(XSRegisters.EDI, 16); XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: 12); XS.Add(XSRegisters.EDI, XSRegisters.EAX); XS.Set(XSRegisters.ECX, XSRegisters.EBP, sourceDisplacement: 8); new CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat }; }
private void DoExecute(Assembler.Assembler assembler, MethodInfo aMethod, ILOpCode aOpCode, OpType aTargetType, bool debugEnabled) { // If thisType is a reference type (as opposed to a value type) then // ptr is dereferenced and passed as the ‘this’ pointer to the callvirt of method // If thisType is a value type and thisType implements method then // ptr is passed unmodified as the ‘this’ pointer to a call of method implemented by thisType // If thisType is a value type and thisType does not implement method then // ptr is dereferenced, boxed, and passed as the ‘this’ pointer to the callvirt of method new Comment(assembler, $"Type = {aTargetType.Value}"); if (aTargetType.Value.BaseType == typeof(ValueType)) { } else if (aTargetType.Value.BaseType == typeof(object)) { throw new NotImplementedException($"Constrained not implemented for {aTargetType.Value}"); } }
/* void Copy(Array sourceArray, ebp + 0x1C * int sourceIndex, ebp + 0x18 * Array destinationArray, ebp + 0x14 * int destinationIndex, ebp + 0x10 * int length, ebp + 0xC * bool reliable); ebp + 0x8 */ public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: SourceArrayDisplacement); XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); // dereference memory handle to pointer XS.Push(XSRegisters.EAX); new CPUx86.Add { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, SourceValue = 12, Size = 32 }; // pointer is at the element size XS.Pop(XSRegisters.EAX); XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); // element size XS.Set(XSRegisters.EBX, XSRegisters.EBP, sourceDisplacement: SourceIndexDisplacement); XS.Multiply(XSRegisters.EBX); XS.Add(XSRegisters.EAX, 16); XS.Set(XSRegisters.ESI, XSRegisters.EBP, sourceDisplacement: SourceArrayDisplacement); XS.Set(XSRegisters.ESI, XSRegisters.ESI, sourceIsIndirect: true); // dereference memory handle to pointer XS.Add(XSRegisters.ESI, XSRegisters.EAX); // source ptr XS.Set(XSRegisters.EDX, XSRegisters.EBP, sourceDisplacement: DestinationArrayDisplacement); XS.Set(XSRegisters.EDX, XSRegisters.EDX, sourceIsIndirect: true); // dereference memory handle to pointer XS.Push(XSRegisters.EDX); new CPUx86.Add { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, SourceValue = 12, Size = 32 }; // pointer is at element size XS.Pop(XSRegisters.EAX); XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); // dereference handle to pointer XS.Set(XSRegisters.ECX, XSRegisters.EBP, sourceDisplacement: DestinationIndexDisplacement); XS.Multiply(XSRegisters.ECX); XS.Add(XSRegisters.EAX, 16); XS.Set(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: DestinationArrayDisplacement); XS.Set(XSRegisters.EDI, XSRegisters.EDI, sourceIsIndirect: true); // dereference handle to pointer XS.Add(XSRegisters.EDI, XSRegisters.EAX); // calculate byte count to copy XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: DestinationArrayDisplacement); XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); // dereference memory handle to pointer XS.Add(XSRegisters.EAX, 12); XS.Set(XSRegisters.EAX, XSRegisters.EAX, sourceIsIndirect: true); XS.Set(XSRegisters.EDX, XSRegisters.EBP, sourceDisplacement: LengthDisplacement); XS.Multiply(XSRegisters.EDX); XS.Set(XSRegisters.ECX, XSRegisters.EAX); new CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat }; }
/*public static void BlockCopy( * Array src, [ebp + 32] * int srcOffset, [ebp + 24] * Array dst, [ebp + 20] * int dstOffset, [ebp + 12] * int count); [ebp + 8] */ public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) { XS.Comment("Source array"); XS.Set(XSRegisters.ESI, XSRegisters.EBP, sourceDisplacement: SourceArrayDisplacement); XS.Add(XSRegisters.ESI, ObjectUtils.FieldDataOffset + 4); XS.Comment("Source index"); XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: SourceIndexDisplacement); XS.Add(XSRegisters.ESI, XSRegisters.EAX); XS.Comment("Destination array"); XS.Set(XSRegisters.EDI, XSRegisters.EBP, sourceDisplacement: DestinationArrayDisplacement); XS.Add(XSRegisters.EDI, ObjectUtils.FieldDataOffset + 4); XS.Comment("Destination index"); XS.Set(XSRegisters.EAX, XSRegisters.EBP, sourceDisplacement: DestinationIndexDisplacement); XS.Add(XSRegisters.EDI, XSRegisters.EAX); XS.Comment("Count"); XS.Set(XSRegisters.ECX, XSRegisters.EBP, sourceDisplacement: CountDisplacement); new CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat }; }