home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / asmutil / zendisk2.zip / LST11-8.ASM < prev    next >
Assembly Source File  |  1990-02-15  |  3KB  |  106 lines

  1. ;
  2. ; *** Listing 11-8 ***
  3. ;
  4. ; Copies overlapping blocks of memory with
  5. ; non-string instructions. To the greatest possible
  6. ; extent, the copy is performed a word at a time.
  7. ;
  8.     jmp    Skip
  9. ;
  10. TEST_LENGTH1    equ    501    ;sample copy length #1
  11. TEST_LENGTH2    equ    1499    ;sample copy length #2
  12. TestArray    db    1500 dup (0)
  13. ;
  14. ; Copies a block of memory CX bytes in length. A value
  15. ; of 0 means "copy zero bytes," since it wouldn't make
  16. ; much sense to copy one 64K block to another 64K block
  17. ; in the same segment, so the maximum length that can
  18. ; be copied is 64K-1 bytes and the minimum length
  19. ; is 0 bytes. Note that both blocks must be in DS. Note
  20. ; also that overlap handling is not guaranteed if either
  21. ; block wraps at the end of the segment.
  22. ;
  23. ; Input:
  24. ;    CX = number of bytes to clear
  25. ;    DS:SI = start of block to copy
  26. ;    DS:DI = start of destination block
  27. ;
  28. ; Output:
  29. ;    none
  30. ;
  31. ; Registers altered: AX, CX, DX, SI, DI
  32. ;
  33. BlockCopyWithOverlap:
  34.     jcxz    BlockCopyWithOverlapDone
  35.             ;guard against zero block size,
  36.             ; since LOOP will execute 64K times
  37.             ; when started with CX=0
  38.     mov    dx,2    ;amount by which to adjust the
  39.             ; pointers in the word-copy loop
  40.     cmp    si,di    ;which way do the blocks overlap, if
  41.             ; they do overlap?
  42.     jae    LowToHigh
  43.             ;source is not below destination, so
  44.             ; we can copy from low to high
  45.  
  46.             ;source is below destination, so we
  47.             ; must copy from high to low
  48.     add    si,cx    ;point to the end of the source
  49.     dec    si    ; block
  50.     add    di,cx    ;point to the end of the destination
  51.     dec    di    ; block
  52.     shr    cx,1    ;divide by 2, copying the odd-byte
  53.             ; status to the Carry flag
  54.     jnc    CopyWordHighToLow ;no odd byte to copy
  55.     mov    al,[si]    ;copy the odd byte
  56.     mov    [di],al
  57.     dec    si    ;advance both pointers
  58.     dec    di
  59. CopyWordHighToLow:
  60.     dec    si    ;point one word lower in memory, not
  61.     dec    di    ; one byte
  62. HighToLowCopyLoop:
  63.     mov    ax,[si]    ;copy a word
  64.     mov    [di],ax
  65.     sub    si,dx    ;advance both pointers 1 word
  66.     sub    di,dx
  67.     loop    HighToLowCopyLoop
  68.     ret
  69. ;
  70. LowToHigh:
  71.     shr    cx,1    ;divide by 2, copying the odd-byte
  72.             ; status to the Carry flag
  73.     jnc    LowToHighCopyLoop    ;no odd byte to copy
  74.     mov    al,[si]    ;copy the odd byte
  75.     mov    [di],al
  76.     inc    si    ;advance both pointers
  77.     inc    di
  78. LowToHighCopyLoop:
  79.     mov    ax,[si]    ;copy a word
  80.     mov    [di],ax
  81.     add    si,dx    ;advance both pointers 1 word
  82.     add    di,dx
  83.     loop    LowToHighCopyLoop
  84. BlockCopyWithOverlapDone:
  85.     ret
  86. ;
  87. Skip:
  88.     call    ZTimerOn
  89. ;
  90. ; First run the case where the destination overlaps & is
  91. ; higher in memory.
  92. ;
  93.     mov    si,offset TestArray
  94.     mov    di,offset TestArray+1
  95.     mov    cx,TEST_LENGTH1
  96.     call    BlockCopyWithOverlap
  97. ;
  98. ; Now run the case where the destination overlaps & is
  99. ; lower in memory.
  100. ;
  101.     mov    si,offset TestArray+1
  102.     mov    di,offset TestArray
  103.     mov    cx,TEST_LENGTH2
  104.     call    BlockCopyWithOverlap
  105.     call    ZTimerOff
  106.