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