🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.pascal.borland
Article #317

Faster MOVE() replacement

#317
From: Robert AH Prins
Date: Mon, 03 May 1999 00:00
203 lines
5749 bytes
After I finally got it working, I thought to myself why the bloody hell did it
take me so long to figure out how to do the overlapping moves...

Below is a replacement for the TP/BP MOVE() routine. Two versions are given,
one a replacement for the routine in the TP6 RTL (and likely the TP/BP7) the
other as an assmbler procedure to be used if you don't have the RTL sources:

BTW, you may also want to have a look at

<http://developer.intel.com/drg/pentiumII/appnotes/813/813.htm>

where Intel itself gives timings for various moves and a C program to test
your own PC.

Here are the routines:

RTL replacement:

; *******************************************************
; *     Turbo Pascal Runtime Library Version 6.0        *
; *     Block Move Routine                              *
; *                                                     *
; *     Copyright (C) 1988,91 Borland International     *
; *     Copyright (C) 1999    Robert AH Prins           *
; *                                                     *
; *     Aligned blockmoves shamelessly adapted from     *
; *     Paul Hsieh's code on                            *
; *     <http://www.pobox.com/~qed/blockcopy.html>      *
; *******************************************************
             TITLE   MEMHMOV

             INCLUDE SE.ASM

CODE         SEGMENT BYTE PUBLIC

             ASSUME  CS:CODE

; Publics

             PUBLIC  MoveMem

; Move standard procedure

MoveMem      PROC    FAR
             MOV     BX, SP
             MOV     DX, DS            ; save TURBO-Pascal data segment
             LDS     SI, SS: [BX+10]   ; source
             LES     DI, SS: [BX+6]    ; destination
             xor     ecx, ecx
             MOV     CX, SS: [BX+4]    ; counter

; *******************************************************
; * 16-bit test, doesn't really take into account that  *
; * values of DS & ES may very well prevent overlap     *
; *******************************************************
             CMP     SI, DI
             JAE     no_overlap        ; source >= destination

overlap:     std
             add     si, cx            ; end of source + 1
             add     di, cx            ; end of destination + 1
             xor     eax, eax
             mov     ax, cx
             sub     cx, di
             sub     cx, ax
             neg     cx
             and     cx, 3

             dec     si                ; last byte of source
             dec     di                ; last byte of destination

             sub     eax, ecx
             jle     @ler

             rep     movsb

             sub     si, 3
             sub     di, 3             ; align on dword

             mov     cx, ax
             and     ax, 3
             shr     cx, 2
             rep     movsd

             add     si, 3             ; add for last movsb
             add     di, 3

ler:
             add     cx, ax
             rep     movsb
             jmps    end_move

no_overlap:  cld
             mov    eax, ecx
             sub    cx, di
             sub    cx, ax
             and    cx, 3
             sub    eax, ecx
             jle    LEndBytes

             rep    movsb
             mov    cx, ax
             and    ax, 3
             shr    cx, 2
             rep    movsd

LEndBytes:
             add    cx, ax
             rep    movsb

end_move:    MOV    DS, DX             ; restore TURBO-Pascal DS
             cld                       ; restore autoincrement!!!
             RET    10                 ; pop parameters and return
MoveMem      ENDP

             ALIGN  4

CODE         ENDS

             END

Pascal assembler procedure:

procedure move(var source, dest; size: word); assembler;
asm
  mov   dx, ds
  segss
  lds   si, source
  segss
  les   di, dest
  db $66; xor   cx, cx
  segss
  mov   cx, size
  cmp   si, di
  jae   @no_over

  std
  add   si, cx
  add   di, cx
  db $66; xor   ax, ax
  mov   ax, cx
  sub   cx, di
  sub   cx, ax
  neg   cx
  and   cx, 3

  dec   si
  dec   di

  db $66;  sub   ax, cx
  jle   @leo

  rep   movsb

  sub   si, 3
  sub   di, 3

  mov   cx, ax
  and   ax, 3
  shr   cx, 2
  rep;  db $66; movsw

  add   si, 3
  add   di, 3

@leo:
  add   cx, ax
  rep   movsb
  jmp   @end_move

@no_over:
  db $66; xor   ax, ax
  mov   ax, cx
  sub   cx, di
  sub   cx, ax
  and   cx, 3
  db $66; sub   ax, cx
  jle   @len

  rep   movsb
  mov   cx, ax
  and   ax, 3
  shr   cx, 2
  rep;  db $66; movsw

@len:
  add   cx, ax
  rep   movsb

@end_move:
  mov    ds, dx
  cld                       { autoincrement!!! }
end; {move}

Please note that at least a 386 is required.

Robert
--
Robert AH Prins
prinsra@williscorroon.com

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    
Technical Details
Message-ID: <7gjtqc$kgq$1@nnrp1.dejanews.com>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 111659,f6859b034dc1da2f,start
X-Google-Attributes: gid111659,public
X-Google-Thread: 108ebd,f6859b034dc1da2f,start
X-Google-Attributes: gid108ebd,public
From: Robert AH Prins <prinsra@williscorroon.com>
Subject: Faster MOVE() replacement
Date: 1999/05/03
Message-ID: <7gjtqc$kgq$1@nnrp1.dejanews.com>
X-Deja-AN: 473451838
To: qed@pobox.com
X-Http-Proxy: 1.0 x9.dejanews.com:80 (Squid/1.1.22) for client 193.130.234.1
Organization: Deja News - The Leader in Internet Discussion
X-Article-Creation-Date: Mon May 03 10:29:34 1999 GMT
Newsgroups: comp.lang.pascal.borland,borland.public.turbopascal
X-Http-User-Agent: Mozilla/4.05 [en] (WinNT; I)