; ; *** Listing 11-7 *** ; ; Copies overlapping blocks of memory with MOVS. ; To the greatest possible extent, the copy is ; performed a word at a time. ; jmp Skip ; TEST_LENGTH1 equ 501 ;sample copy length #1 TEST_LENGTH2 equ 1499 ;sample copy length #2 TestArray db 1500 dup (0) ; ; Copies a block of memory CX bytes in length. A value ; of 0 means "copy zero bytes," since it wouldn't make ; much sense to copy one 64K block to another 64K block ; in the same segment, so the maximum length that can ; be copied is 64K-1 bytes and the minimum length ; is 0 bytes. Note that both blocks must be in DS. Note ; also that overlap handling is not guaranteed if either ; block wraps at the end of the segment. ; ; Input: ; CX = number of bytes to clear ; DS:SI = start of block to copy ; DS:DI = start of destination block ; ; Output: ; none ; ; Registers altered: CX, DX, SI, DI, ES ; ; Direction flag cleared ; BlockCopyWithOverlap: mov dx,ds ;source and destination are in the mov es,dx ; same segment cmp si,di ;which way do the blocks overlap, if ; they do overlap? jae LowToHigh ;source is not below destination, so ; we can copy from low to high ;source is below destination, so we ; must copy from high to low add si,cx ;point to the end of the source dec si ; block add di,cx ;point to the end of the destination dec di ; block std ;copy from high addresses to low shr cx,1 ;divide by 2, copying the odd-byte ; status to the Carry flag jnc CopyWordHighToLow ;no odd byte to copy movsb ;copy the odd byte CopyWordHighToLow: dec si ;point one word lower in memory, not dec di ; one byte rep movsw ;move the rest of the block cld ret ; LowToHigh: cld ;copy from low addresses to high shr cx,1 ;divide by 2, copying the odd-byte ; status to the Carry flag jnc CopyWordLowToHigh ;no odd byte to copy movsb ;copy the odd byte CopyWordLowToHigh: rep movsw ;move the rest of the block ret ; Skip: call ZTimerOn ; ; First run the case where the destination overlaps & is ; higher in memory. ; mov si,offset TestArray mov di,offset TestArray+1 mov cx,TEST_LENGTH1 call BlockCopyWithOverlap ; ; Now run the case where the destination overlaps & is ; lower in memory. ; mov si,offset TestArray+1 mov di,offset TestArray mov cx,TEST_LENGTH2 call BlockCopyWithOverlap call ZTimerOff