Beispiel #1
0
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xEndLabel = GetLabel(aMethod, aOpCode) + ".End";

            // size
            XS.Pop(ECX);
            // value
            XS.Pop(EBX);
            // address
            XS.Pop(EDI);

            XS.Compare(ECX, 0);
            XS.Jump(ConditionalTestEnum.Equal, xEndLabel);

            XS.Set(EDI, BL, destinationIsIndirect: true);

            XS.Compare(ECX, 1);
            XS.Jump(ConditionalTestEnum.Equal, xEndLabel);

            XS.Set(ESI, EDI);
            XS.Increment(EDI);
            XS.Decrement(ECX);

            new Movs {
                Prefixes = InstructionPrefixes.Repeat, Size = 8
            };

            XS.Label(xEndLabel);
        }
        /* void Copy(
         *           Array sourceArray,			ebp + 36
         *			 int sourceIndex,			ebp + 28
         *			 Array destinationArray,	ebp + 24
         *			 int destinationIndex,		ebp + 16
         *			 int length,				ebp + 12
         *			 bool reliable);			ebp + 8
         */

        public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
        {
            var xArrayCopyReverseLabel     = "ArrayCopy_Reverse";
            var xArrayCopyReverseLoopLabel = "ArrayCopy_Reverse_Loop";
            var xArrayCopyEndLabel         = "ArrayCopy_End";

            XS.Comment("Source");
            XS.Comment("Element size");
            XS.Set(EAX, EBP, sourceDisplacement: SourceArrayDisplacement);
            XS.Add(EAX, ObjectUtils.FieldDataOffset);
            XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
            XS.Comment("Source ptr");
            XS.Set(EBX, EBP, sourceDisplacement: SourceIndexDisplacement);
            XS.Multiply(EBX);
            XS.Add(EAX, ObjectUtils.FieldDataOffset + 4); // first element
            XS.Set(ESI, EBP, sourceDisplacement: SourceArrayDisplacement);
            XS.Add(ESI, EAX);                             // source ptr

            XS.Comment("Destination");
            XS.Comment("Element size");
            XS.Set(EAX, EBP, sourceDisplacement: DestinationArrayDisplacement);
            XS.Add(EAX, ObjectUtils.FieldDataOffset);
            XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
            XS.Comment("Destination ptr");
            XS.Set(ECX, EBP, sourceDisplacement: DestinationIndexDisplacement);
            XS.Multiply(ECX);
            XS.Add(EAX, ObjectUtils.FieldDataOffset + 4); // first element
            XS.Set(EDI, EBP, sourceDisplacement: DestinationArrayDisplacement);
            XS.Add(EDI, EAX);                             // destination ptr

            XS.Compare(EDI, ESI);
            XS.Jump(ConditionalTestEnum.Equal, xArrayCopyEndLabel);

            XS.Comment("Copy byte count");
            XS.Comment("Element size");
            XS.Set(EAX, EBP, sourceDisplacement: DestinationArrayDisplacement);
            XS.Add(EAX, ObjectUtils.FieldDataOffset);
            XS.Set(EAX, EAX, sourceIsIndirect: true); // element size
            XS.Comment("Count");
            XS.Set(EDX, EBP, sourceDisplacement: LengthDisplacement);

            // if length is 0, jump to end
            XS.Compare(EDX, 0);
            XS.Jump(ConditionalTestEnum.Equal, xArrayCopyEndLabel);

            XS.Multiply(EDX);
            XS.Set(ECX, EAX);

            XS.Compare(EDI, ESI);
            XS.Jump(ConditionalTestEnum.GreaterThan, xArrayCopyReverseLabel);

            new Movs {
                Size = 8, Prefixes = InstructionPrefixes.Repeat
            };

            XS.Jump(xArrayCopyEndLabel);

            XS.Label(xArrayCopyReverseLabel);

            XS.Add(ESI, ECX);
            XS.Add(EDI, ECX);

            XS.Label(xArrayCopyReverseLoopLabel);

            XS.Decrement(ESI);
            XS.Decrement(EDI);
            XS.Decrement(ECX);

            XS.Set(AL, ESI, sourceIsIndirect: true);
            XS.Set(EDI, AL, destinationIsIndirect: true);

            XS.Compare(ECX, 0);
            XS.Jump(ConditionalTestEnum.NotEqual, xArrayCopyReverseLoopLabel);

            XS.Label(xArrayCopyEndLabel);
        }