public static unsafe uint Add(uint *location, uint value) { Asm.MOV(R32.EDX, &value); Asm.LOCK(); Asm.ADD(location, R32.EDX); return(*location); }
public static unsafe void MemCopy(uint src, uint dst, uint count) { Asm.CLD(); Asm.MOV(R32.ECX, &count); Asm.MOV(R32.ESI, &src); Asm.MOV(R32.EDI, &dst); Asm.CMP(R32.ESI, R32.EDI); Asm.JA("FMove8"); Asm.STD(); Asm.ADD(R32.ESI, R32.ECX); Asm.ADD(R32.EDI, R32.ECX); Asm.LABEL("BMove8"); Asm.SHR(R32.ECX, 1); // divide count by 2 (8bit -> 16bit blocks) Asm.JNC("BMove16"); // if carry flag has not been set, skip next instruction Asm.MOVSB(); // move a byte (8bit) first Asm.LABEL("BMove16"); Asm.SHR(R32.ECX, 1); // divide count by 2 (16bit -> 32bit blocks) Asm.JNC("BMove32"); // if carry flag has not been set, skip next instruction Asm.MOVSW(); // move short (16bit) first Asm.LABEL("BMove32"); Asm.INC(R32.ECX); Asm.REP(); Asm.MOVSD(); // move everything else in 32bit blocks Asm.JMP("EndMove"); Asm.LABEL("FMove8"); Asm.SHR(R32.ECX, 1); // divide count by 2 (8bit -> 16bit blocks) Asm.JNC("FMove16"); // if carry flag has not been set, skip next instruction Asm.MOVSB(); // move a byte (8bit) first Asm.LABEL("FMove16"); Asm.SHR(R32.ECX, 1); // divide count by 2 (16bit -> 32bit blocks) Asm.JNC("FMove32"); // if carry flag has not been set, skip next instruction Asm.MOVSW(); // move short (16bit) first Asm.LABEL("FMove32"); Asm.REP(); Asm.MOVSD(); // move everything else in 32bit blocks Asm.LABEL("EndMove"); }