Contributor: DAVID STIDOLPH

(*
If you have the VCL source look at TMemoryStream - it is pretty efficient
for 286 code.  If you are willing to only run on 386 machines you can use
386 32-bit addressing in assembly code to access the data.  Following the
includion I have placed some assembly code I have written to do this.  It
compiles under MASM and is linked with the {$L} directive.  The reason I
wrote this code was for a WinG module I am still working on.  Anyone is
welcome to use this code, but I would like to see work done using it.

>The TMemoryStream has a property TMemoryStream.Memory, which returns a
>pointer to the actual location of the data in memory. To access the 
>first byte I could just use TMemoryStream.Memory^
>
>The problem is: If I want to for example get bytes 15 to 21 out of the
>stream, is there a way to point to the location of this data?
>I do not want to use the Seek/Read function, as this is a lot slower
>than using direct memory access.
*)

{$L move.obj}

procedure Move32(pSrc: Pointer; srcOffset: Longint; pDest: Pointer;
destOffset: Longint; len: Longint); external;

Assembly code (move.asm)
	.MODEL large, PASCAL
	.386
	OPTION SCOPED

LPBYTE TYPEDEF FAR PTR BYTE

Move32 PROTO FAR PASCAL,
		 pSrc:LPBYTE, srcOffset:DWORD,
		 pDest: LPBYTE, destOffset:DWORD,
		 len:DWORD

	.Code

Move32	PROC FAR PASCAL USES ds es esi edi,
		pSrc: LPBYTE, srcOffset:DWORD,
		pDest: LPBYTE, destOffset:DWORD,
		len:DWORD
	cld			;move forward through memory
	mov	esi,0		;clear index registers - noteably the top of
	mov	edi,0		;the 32 bit (upper 16 bits) registers.

	lds	si,pSrc		;load ds/si with pointer to base source
	les	di,pDest	;load es/di with pointer to base destination
	add	esi,srcOffset	;add in offset to desired point
	add	edi,destOffset	;add in offset to desired point
	mov	ecx,len		;get the length of the move
	shr	ecx,2		;divide by 4 for DWORD moves
	rep	movsd		;if ecx is zero no move is done
	mov	ecx,len		;pick up length to do remainder
	and	ecx,3		;only move 0-3 bytes
	rep	movsb		;if ecx is zero no move is done
	retf			;far return
Move32	ENDP

END