RTUEE / EC / EEEYr 2024 · Sem 52024

Q4Microprocessor

Question

10 marks

Q.4. Write a program to transfer one block of data into another block in same order in 8085.

Answer

An 8085 assembly program to transfer a block of data from a source memory location to a destination in the same order uses register pairs HL and DE as source and destination pointers, register C (or B) as a byte counter, and a loop using LDAX/MOV, STAX/MOV and INX instructions to copy each byte sequentially, terminating with DCR/JNZ.

Objective: transfer a block of N data bytes stored starting at a source memory address to a destination memory address, preserving the same byte order (i.e., the first source byte goes to the first destination address, the second source byte to the second destination address, and so on).

Algorithm: initialize the HL register pair as a pointer to the source block's starting address, the DE register pair as a pointer to the destination block's starting address, and a counter register (e.g., C) with the total number of bytes N to be transferred; then repeatedly read a byte from the memory location pointed to by HL (using MOV A, M), write that byte to the memory location pointed to by DE (using STAX D), increment both HL and DE to point to the next respective memory location, decrement the counter, and repeat this process until the counter reaches zero.

asm
        MVI C, 0AH        ; number of bytes to transfer, e.g., N=10 (0AH)
        LXI H, 2000H      ; HL = source block starting address
        LXI D, 3000H      ; DE = destination block starting address
LOOP:   MOV A, M          ; A = [HL]  (read byte from source)
        STAX D            ; [DE] = A  (write byte to destination)
        INX H             ; increment source pointer
        INX D             ; increment destination pointer
        DCR C             ; decrement byte counter
        JNZ LOOP          ; repeat until all N bytes transferred
        HLT               ; stop after transfer complete

Explanation of execution: the program begins by loading the total byte count N (here assumed to be 10, or 0AH, though this value would be set according to the actual block size for a specific problem) into register C, and initializing HL to point to the first byte of the source data block (assumed at address 2000H) and DE to point to the first byte of the destination block (assumed at address 3000H). The LOOP then executes N times: MOV A, M reads the byte currently pointed to by HL into the accumulator; STAX D writes that byte from the accumulator to the memory location currently pointed to by the DE register pair; INX H and INX D then advance both pointers to the next memory location for the following iteration; DCR C decrements the remaining byte counter and sets the Zero flag if it reaches 0; and JNZ LOOP causes execution to jump back to LOOP if the counter has not yet reached zero (i.e., more bytes remain to transfer), or falls through to HLT once all N bytes have been successfully copied, since JNZ does not take the jump once DCR C produces a zero result.

Note on preserving order: since both HL (source) and DE (destination) pointers are incremented (INX, moving forward) together on each iteration, the byte originally at source address 2000H is copied to destination address 3000H first, the byte at 2001H is copied to 3001H second, and so on — this forward-incrementing approach directly preserves the original byte ordering from source to destination, which is precisely the requirement specified in the problem; if the two memory blocks were to overlap in a way where copying forward could overwrite not-yet-read source bytes, a reverse-order (decrementing pointer) transfer approach would instead be required to avoid data corruption, though for this general non-overlapping block transfer case, the straightforward forward-incrementing approach shown here is the standard, correct solution.

Why MOV A, M and STAX D Are Used Rather Than the Reverse

The choice of MOV A, M (rather than LDAX, which only works with BC or DE, not HL) to read the source byte, and STAX D (rather than MOV M, A, which would require the destination pointer to be in HL) to write the destination byte, is dictated directly by which register pairs the 8085 instruction set allows for register-indirect addressing with each instruction: MOV r, M and MOV M, r use HL exclusively as the indirect address pointer, whereas LDAX and STAX use only BC or DE. Since the program needs two independent, simultaneously-active pointers (one for source, one for destination), and HL is the only pair usable with the general-purpose MOV M instructions, HL is naturally assigned to the source pointer (read via MOV A, M) while DE is assigned to the destination pointer (written via STAX D); had the roles been reversed, the program would require an extra instruction (such as XCHG, to swap HL and DE) inside the loop, which would waste both program memory and execution time without providing any benefit, since XCHG would simply need to be reversed again on the following iteration.

Edge cases and limitations: this program handles blocks of up to 256 bytes directly, since the counter register C is only 8 bits wide and DCR C/JNZ LOOP cannot count beyond 255 before wrapping to zero; for larger block transfers, a 16-bit counter (held in a register pair, decremented and tested for zero using a compound sequence such as DCX rp followed by testing both bytes, since 8085 lacks a direct 16-bit conditional-decrement-and-jump instruction) would be required instead. Additionally, this program assumes N is at least 1 — if N were allowed to be 0, the DCR C; JNZ LOOP structure as written would still execute the loop body once before the counter underflows to FFH and continues looping 255 more times, a classic off-by-one bug avoidable by testing the counter for zero before entering the loop the first time (e.g., using an initial MOV A, C; ORA A; JZ DONE check ahead of the loop) whenever N might legitimately be zero in a given application.

Generalization: this same source-pointer/destination-pointer/counter loop structure is the standard template underlying nearly all 8085 block-oriented operations — block search (comparing each byte against a target value instead of transferring it), block fill (writing a constant value to every location instead of copying from a source), and block comparison (comparing corresponding bytes of two blocks and branching on the first mismatch) all reuse the identical pointer-increment-and-count-down loop skeleton, differing only in what operation is performed on the byte(s) referenced by the pointer(s) within the loop body.

Back to Paper