RTUEE / EC / EEEYr 2022 · Sem 52022

Q1Microprocessor

Question

15 marks

Q.1. A binary coded decimal number between 0 and 99 is stored in R/W memory location called the "Input Buffer" (INBUF). Write a main program and a conversion subroutine (BCDBIN) to convert BCD number into its equivalent binary number. Store the result in a memory location defined as the output buffer (OUTBUF).

Answer

The BCD-to-binary conversion subroutine processes each BCD digit weight by weight, computing binary = tens_digit×10 + units_digit using repeated addition/multiplication via shifts and adds, since the 8085 lacks a direct hardware multiply instruction, with the main program calling the BCDBIN subroutine and storing the final binary result in OUTBUF.

Problem: a 2-digit BCD number (representing any value from 0 to 99) is stored in a memory location INBUF, packed as a single byte with the tens digit in the upper nibble and the units digit in the lower nibble (e.g., BCD 47 is stored as the byte 47H, upper nibble = 4, lower nibble = 7). We must write a main program and a BCDBIN conversion subroutine to compute the equivalent pure binary value (e.g., BCD 47 → binary value 2FH = 47 decimal) and store the result in OUTBUF.

Algorithm: the packed BCD byte is first split into its two separate BCD digits (tens digit = upper nibble, units digit = lower nibble) by masking and shifting; the binary equivalent is then computed as Binary = (tens_digit × 10) + units_digit, using repeated addition to implement the multiplication by 10 (since the 8085 has no direct hardware multiply instruction, unlike the 8051's MUL AB), specifically as (tens_digit × 8) + (tens_digit × 2) = tens_digit shifted left 3 times, plus tens_digit shifted left 1 time, which together equal tens_digit × 10 using only shift (add-to-itself) and add operations.

asm
; Main Program
START:  LXI H, INBUF       ; HL points to input BCD byte
        MOV A, M           ; A = packed BCD byte
        CALL BCDBIN        ; convert to binary, result returned in A
        LXI H, OUTBUF      ; HL points to output location
        MOV M, A           ; store binary result
        HLT

; Subroutine BCDBIN: input packed BCD in A, returns binary in A
BCDBIN: PUSH B             ; save B, C (preserve caller's registers)
        MOV B, A           ; B = copy of packed BCD byte
        ANI 0F0H           ; mask to isolate upper nibble (tens digit)
        RRC                ; 
        RRC                ; shift right 4 times to align tens digit
        RRC                ; to bit positions 0-3
        RRC
        MOV C, A           ; C = tens digit (0-9), isolated
        MOV A, C           ; A = tens digit
        MOV D, A           ; D = tens digit (keep original copy)
        RLC                ; A = tens_digit * 2  (shift left 1)
        RLC
        RLC                ; A = tens_digit * 8  (shift left 3 total... )
        ; (Simplify: compute tens*10 = tens*8 + tens*2 via two shifted copies)
        MOV C, A           ; C = tens_digit * 8
        MOV A, D
        RLC                ; A = tens_digit * 2
        ADD C              ; A = tens_digit*2 + tens_digit*8 = tens_digit*10
        MOV C, A           ; C = tens_digit * 10 (partial binary result)
        MOV A, B           ; A = original packed BCD byte
        ANI 0FH            ; mask to isolate lower nibble (units digit)
        ADD C              ; A = (tens_digit*10) + units_digit = final binary value
        POP B              ; restore B, C
        RET

Explanation: the main program loads the packed BCD byte from INBUF into the accumulator, calls the BCDBIN subroutine (which performs the actual conversion and returns the binary result in the accumulator), then stores this returned binary value into OUTBUF. Within BCDBIN, the packed byte is first masked with 0F0H and rotated right four times to isolate and right-align the tens digit (originally in the upper nibble) into the lower 4 bits; this tens-digit value is then multiplied by 10 using only shift (RLC, effectively multiplying by 2 with each rotation, since RLC operates as an arithmetic left-shift here for values not exceeding 7 bits significant) and add operations — specifically computing tens×8 (via three left-shifts) and tens×2 (via one left-shift) separately and adding them together to get tens×10, since 8+2=10 — because the 8085 instruction set lacks a direct hardware multiply instruction unlike more advanced processors, requiring this shift-and-add technique to implement multiplication by a constant. Finally, the original packed byte is masked with 0FH to isolate the units digit (already correctly positioned in the lower nibble), and this units digit is added to the previously computed tens×10 partial result, yielding the complete binary equivalent of the original 2-digit BCD number, which the subroutine returns to the caller via the accumulator register, following the standard convention of preserving (via PUSH/POP) any registers used internally by the subroutine that the calling program did not expect to be altered.

Why RRC/RLC rather than dedicated shift instructions: the 8085 instruction set provides only rotate instructions (RLC, RRC — rotate through the accumulator itself, wrapping the bit that falls off one end back onto the other end) and their carry-inclusive variants (RAL, RAR — rotate through the carry flag), rather than true logical/arithmetic shift instructions that would discard the bit falling off the end and shift in a zero. This is why the program first masks the accumulator with ANI 0F0H (clearing the lower nibble to zero) before rotating right — since RRC would otherwise wrap the low-order bits (which have not yet been cleared) around into the vacated high-order bit positions, corrupting the isolated tens-digit value; by first zeroing out the bits that would otherwise wrap around, the subsequent RRC operations correctly behave as an effective right-shift for the purpose of this specific isolation task, since there are no stray 1-bits left in the wrapped-around positions to interfere with the result.

Worked numerical trace (example: packed BCD = 47H, representing decimal 47): starting with A = 47H (0100 0111 binary). After ANI 0F0H: A = 40H (0100 0000). After four RRC rotations: A = 04H (tens digit isolated and right-aligned = 4). This value 04H is copied to C, then to D as a backup. The sequence of three RLC instructions applied to a copy of this value computes 4×2=8 (04H→08H after 1 RLC), continuing to 8×2=16=10H (after 2nd RLC), continuing to 16×2=32=20H (after 3rd RLC) — so after three RLCs, A holds 20H (32 decimal) = tens_digit×8 = 4×8 = 32, confirming the shift-left-three-times = multiply-by-8 relationship. Separately, one RLC applied to the backed-up copy (D=04H) gives A=08H (8 decimal) = tens_digit×2 = 4×2 = 8. Adding these two partial products: 32+8 = 40 = tens_digit×10 = 4×10, correctly computed using only shifts and one addition instead of a direct multiply. Finally, extracting the units digit from the original packed byte (47H ANI 0FH = 07H = 7 decimal) and adding it to the 40 (tens×10) partial result gives 40+7 = 47 decimal = 2FH in hexadecimal, which is exactly the correct pure-binary representation of the original decimal value 47 that was packed as the BCD byte 47H — confirming the algorithm's correctness on this worked example.

Range and validity considerations: since the problem specifies the input BCD number lies between 0 and 99 inclusive, the maximum possible binary result is 99 decimal = 63H, which comfortably fits within a single 8-bit accumulator/output byte (whose maximum unsigned range is 0-255), so no special handling for result overflow beyond a single byte is needed for this particular problem's stated input range; if the subroutine were instead required to handle a wider range of packed BCD input (such as a 3-digit or 4-digit packed BCD value), the resulting binary value could exceed 255 and would require the result to be returned as a 16-bit value split across two registers (e.g., HL), with the multiplication-by-10 and addition steps correspondingly extended to properly propagate any carry between the low and high result bytes.

Why register B is used as a temporary holding register: at the very start of BCDBIN, the original packed BCD byte (passed in via the accumulator) is immediately copied into register B, before the accumulator itself is destructively modified (masked and rotated) to extract the tens digit; this preserves an unaltered copy of the original input so that, later in the subroutine, the units digit can still be correctly extracted (by masking this preserved copy in B with 0FH) even though the accumulator has by then already been used and overwritten multiple times for the tens-digit extraction and multiplication steps — a standard assembly-language pattern of saving an operand to a spare register before performing destructive operations on the accumulator that would otherwise lose access to the original value needed again later in the same routine.

Back to Paper