mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 05:18:38 +00:00
60 lines
5.3 KiB
C#
60 lines
5.3 KiB
C#
using Cosmos.IL2CPU.Plugs;
|
|
using XSharp.Compiler;
|
|
using CPUx86 = Cosmos.Assembler.x86;
|
|
|
|
namespace Cosmos.Core.Plugs.System.Assemblers
|
|
{
|
|
public class Array_InternalCopy : AssemblerMethod
|
|
{
|
|
private const int SourceArrayDisplacement = 0x1C;
|
|
private const int SourceIndexDisplacement = 0x18;
|
|
private const int DestinationArrayDisplacement = 0x14;
|
|
private const int DestinationIndexDisplacement = 0x10;
|
|
private const int LengthDisplacement = 0xC;
|
|
|
|
/* 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)
|
|
{
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = SourceArrayDisplacement };
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true }; // dereference memory handle to pointer
|
|
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
|
new CPUx86.Add { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, SourceValue = 12, Size = 32 }; // pointer is at the element size
|
|
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true }; // element size
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EBX, SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = SourceIndexDisplacement };
|
|
XS.Multiply(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EBX));
|
|
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), 16);
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESI, SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = SourceArrayDisplacement };
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ESI, SourceReg = CPUx86.RegistersEnum.ESI, SourceIsIndirect = true }; // dereference memory handle to pointer
|
|
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ESI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX)); // source ptr
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EDX, SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = DestinationArrayDisplacement };
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EDX, SourceReg = CPUx86.RegistersEnum.EDX, SourceIsIndirect = true }; // dereference memory handle to pointer
|
|
XS.Push(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
|
new CPUx86.Add { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, SourceValue = 12, Size = 32 }; // pointer is at element size
|
|
XS.Pop(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true }; // dereference handle to pointer
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.ECX, SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = DestinationIndexDisplacement };
|
|
XS.Multiply(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX));
|
|
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), 16);
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EDI, SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = DestinationArrayDisplacement };
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EDI, SourceReg = CPUx86.RegistersEnum.EDI, SourceIsIndirect = true }; // dereference handle to pointer
|
|
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDI), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
|
|
|
// calculate byte count to copy
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = DestinationArrayDisplacement };
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true }; // dereference memory handle to pointer
|
|
XS.Add(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX), 12);
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EAX, SourceReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true };
|
|
new CPUx86.Mov { DestinationReg = CPUx86.RegistersEnum.EDX, SourceReg = CPUx86.RegistersEnum.EBP, SourceIsIndirect = true, SourceDisplacement = LengthDisplacement };
|
|
XS.Multiply(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EDX));
|
|
XS.Set(XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.ECX), XSRegisters.OldToNewRegister(CPUx86.RegistersEnum.EAX));
|
|
new CPUx86.Movs { Size = 8, Prefixes = CPUx86.InstructionPrefixes.Repeat };
|
|
}
|
|
}
|
|
}
|