<P> The following 8086 / 8088 assembler source code is for a subroutine named _memcpy that copies a block of data bytes of a given size from one location to another . The data block is copied one byte at a time, and the data movement and looping logic utilizes 16 - bit operations . </P> <Table> <Tr> <Td> 0000: 1000 0000: 1000 0000: 1000 55 0000: 1001 89 E5 0000: 1003 06 0000: 1004 8B 4E 06 0000: 1007 E3 11 0000: 1009 8B 76 04 0000: 100C 8B 7E 02 0000: 100F 1E 0000: 1010 07 0000: 1011 8A 04 0000: 1013 88 05 0000: 1015 46 0000: 1016 47 0000: 1017 49 0000: 1018 75 F7 0000: 101A 07 0000: 101B 5D 0000: 101C 29 C0 0000: 101E C3 0000: 101F </Td> <Td>; _memcpy (dst, src, len); Copy a block of memory from one location to another .;; Entry stack parameters; (BP + 6) = len, Number of bytes to copy; (BP + 4) = src, Address of source data block; (BP + 2) = dst, Address of target data block;; Return registers; AX = Zero org 1000h; Start at 0000: 1000h _memcpy proc push bp; Set up the call frame mov bp, sp push es; Save ES mov cx, (bp + 6); Set CX = len jcxz done; If len = 0, return mov si, (bp + 4); Set SI = src mov di, (bp + 2); Set DI = dst push ds; Set ES = DS pop es loop mov al, (si); Load AL from (src) mov (di), al; Store AL to (dst) inc si; Increment src inc di; Increment dst dec cx; Decrement len jnz loop; Repeat the loop done pop es; Restore ES pop bp; Restore previous call frame sub ax, ax; Set AX = 0 ret; Return end proc </Td> </Tr> </Table> <Tr> <Td> 0000: 1000 0000: 1000 0000: 1000 55 0000: 1001 89 E5 0000: 1003 06 0000: 1004 8B 4E 06 0000: 1007 E3 11 0000: 1009 8B 76 04 0000: 100C 8B 7E 02 0000: 100F 1E 0000: 1010 07 0000: 1011 8A 04 0000: 1013 88 05 0000: 1015 46 0000: 1016 47 0000: 1017 49 0000: 1018 75 F7 0000: 101A 07 0000: 101B 5D 0000: 101C 29 C0 0000: 101E C3 0000: 101F </Td> <Td>; _memcpy (dst, src, len); Copy a block of memory from one location to another .;; Entry stack parameters; (BP + 6) = len, Number of bytes to copy; (BP + 4) = src, Address of source data block; (BP + 2) = dst, Address of target data block;; Return registers; AX = Zero org 1000h; Start at 0000: 1000h _memcpy proc push bp; Set up the call frame mov bp, sp push es; Save ES mov cx, (bp + 6); Set CX = len jcxz done; If len = 0, return mov si, (bp + 4); Set SI = src mov di, (bp + 2); Set DI = dst push ds; Set ES = DS pop es loop mov al, (si); Load AL from (src) mov (di), al; Store AL to (dst) inc si; Increment src inc di; Increment dst dec cx; Decrement len jnz loop; Repeat the loop done pop es; Restore ES pop bp; Restore previous call frame sub ax, ax; Set AX = 0 ret; Return end proc </Td> </Tr> <P> The code above uses the BP (base pointer) register to establish a call frame, an area on the stack that contains all of the parameters and local variables for the execution of the subroutine . This kind of calling convention supports reentrant and recursive code, and has been used by most ALGOL - like languages since the late 1950s . </P>

How many segments are active at a time in 8086