home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / MSJV5-3.ZIP / VLB.ZIP / LMEMMOVE.ASM < prev    next >
Assembly Source File  |  1990-05-01  |  4KB  |  106 lines

  1. ;  lmemmove.asm           far version of memmove
  2.  
  3. INCLUDE         SETUP.H
  4.  
  5. CLIB            SEGMENT  WORD PUBLIC 'CODE'
  6. CLIB            ENDS
  7.  
  8. CLIB            SEGMENT
  9. ASSUME          CS: CLIB
  10.  
  11. PUBLIC          lmemmove
  12.  
  13. lmemmove        PROC    FAR
  14.  
  15. Destination     EQU     DWORD   PTR [bp] + 12
  16. Source          EQU     DWORD   PTR [bp] + 8
  17. Count           EQU     WORD    PTR [bp] + 6
  18.  
  19.                 ENTRY   0
  20.  
  21.                 lds     si, Source      ; DS:SI = Source
  22.                 les     di, Destination ; ES:DI = Destination
  23.                 mov     ax, di          ; Dest. in AX for return 
  24.                 mov     cx, Count       ; cx = number bytes to move
  25.                 jcxz    done            ; if cx = 0,  nothing to copy
  26.  
  27. ;
  28. ; Check for overlapping buffers:
  29. ;        If segments are different, assume no overlap
  30. ;                Do normal (Upwards) Copy
  31. ;        Else If (Dest. <= Source) Or (Dest.>= Source + Count) Then
  32. ;                Do normal (Upwards) Copy
  33. ;        Else
  34. ;                Do Downwards Copy to avoid propogation
  35. ;
  36.                 mov     ax, es          ; compare the segments
  37.                 cmp     ax, WORD PTR (Source+2)
  38.                 jne     CopyUp
  39.                 cmp     di, si          ; Source <= Destination ?
  40.                 jbe     CopyUp
  41.  
  42.                 mov     ax, si
  43.                 add     ax, cx
  44.                 cmp     di, ax          ; Dest. >= (Source + Count) ?
  45.                 jae     CopyUp
  46. ;
  47. ; Copy Down to avoid propogation in overlapping buffers
  48. ;
  49.                 mov     ax, di          ; AX = return value (offset)
  50.                 
  51.                 add     si, cx
  52.                 add     di, cx
  53.                 dec     si              ; DS:SI = Source + Count - 1
  54.                 dec     di              ; ES:DI = Dest. + Count - 1
  55.                 std                     ; Set Direction Flag = Down
  56.                 rep     movsb
  57.                 cld                     ; Set Direction Flag = Up
  58.                 jmp     short done
  59.  
  60. CopyUp:
  61.                 mov     ax, di          ; AX = return value (offset)
  62. ;
  63. ; There are 4 types of word alignment of "Source" and "Destination":
  64. ;        1. Source and Destination are both even        (best case)
  65. ;        2. Source is even and Destination is odd
  66. ;        3. Source is odd and Destination is even
  67. ;        4. Source and Destination are both odd        (worst case)
  68. ;
  69. ; Case #4 is much faster if a single byte is copied before the
  70. ; REP MOVSW instruction.  Cases #2 and #3 are effectively unaffected
  71. ; by such an operation.  To maximum the speed of this operation,
  72. ; only DST is checked for alignment.  For cases #2 and #4, the first
  73. ; byte will be copied before the REP MOVSW.
  74. ;
  75.                 test    al, 1      ; fast check for Dest. odd address
  76.                 jz      move
  77.  
  78.                 movsb              ; move a byte to improve alignment
  79.                 dec     cx
  80. ;
  81. ; Now the bulk of the copy is done using REP MOVSW.  This is much
  82. ; faster than a REP MOVSB if the Source and Dest. addresses are both
  83. ; word aligned and the processor has a 16-bit bus.  Depending on
  84. ; the initial alignment and the size of the region moved, there
  85. ; may be an extra byte left over to be moved.  This is handled
  86. ; by the REP MOVSB, which moves either 0 or 1 bytes.
  87. ;
  88. move:
  89.                 shr     cx, 1           ; Shift CX for Count of words
  90.                 rep     movsw           ; CF set if 1 byte left over
  91.                 adc     cx, cx          ; CX = 1 or 0, - Carry Flag
  92.                 rep     movsb           ; possible final byte
  93. ;
  94. ; Return the "Destination" address in AX/DX:AX
  95. ;
  96. done:
  97.                 EXIT    10
  98.  
  99. lmemmove        ENDP
  100.  
  101. CLIB            ENDS
  102.  
  103.                 END
  104.