CSC167 Microprocessor

MicroprocessorUnit 820 min read

Assembly Language Programming & Directives: Syntax, Logic, and 8085/8086 Code

Unit 8 of Microprocessor covers assembly language programming fundamentals, directives, and practical coding for 8085/8086 microprocessors, including data manipulation, loops, string operations, and arithmetic logic—essential for TU exams and real-world embedded systems.

TAKEAWAYS:

  • Directives vs. Instructions: Directives (e.g., DB, DW) are non-executable assembly commands for the assembler, while instructions (e.g., MOV, ADD) are executed by the microprocessor.
  • 8085 vs. 8086 Syntax: 8085 uses 8-bit registers (A, B, C, D, E, H, L) and 16-bit registers (HL, BC, DE, SP) with single-letter opcodes, while 8086 uses 16-bit registers (AX, BX, CX, DX) and segmented memory addressing.
  • Loop Structures: Use DJNZ (8085) or LOOP (8086) for iterative tasks, with careful register management to avoid infinite loops.
  • String Manipulation: Directives like DB define strings, while instructions like MOVSB (8086) or LXI H + MOV M (8085) process them.
  • Arithmetic Logic: Master division/multiplication via repeated addition/subtraction (e.g., DCR, INR) and use DAA (8085) for BCD adjustments.
  • Error Handling: Check carry flags (CY) and zero flags (Z) to validate operations (e.g., division by zero).

1. Assembly Language Basics: Syntax and Structure

Assembly language is a low-level programming language where each instruction corresponds to a microprocessor operation. It uses mnemonics (e.g., MOV, ADD) and operands (registers, memory, or immediate values). Unlike high-level languages, assembly requires explicit control over hardware resources like registers and memory.

Key Components of an Assembly Program

  1. Directives: Instructions for the assembler (not the microprocessor).
    • DB (Define Byte): Stores 8-bit data.
      DB 5Ah, 0FFh  ; Defines two bytes: 5Ah and FFh
      
    • DW (Define Word): Stores 16-bit data.
      DW 1234h      ; Defines a 16-bit word
      
    • EQU: Assigns a constant value.
      COUNT EQU 10   ; COUNT = 10
      
    • ORG: Sets the origin (starting address) of the program.
      ORG 2000h      ; Program starts at 2000h
      
0481215Opcode8 bitsOperands8 bits
Example 8085 instruction format (1-byte opcode + 1-byte operand).
  1. Instructions: Executable commands for the microprocessor.
    • Data Transfer: MOV, LXI, LHLD, SHLD.
    • Arithmetic/Logic: ADD, SUB, INR, DCR, DAA, CMP.
    • Control Flow: JMP, CALL, RET, DJNZ, LOOP.
    • Stack Operations: PUSH, POP.

Example: Defining Data and Initializing Registers

ORG 3000h
DATA1 DB 10h, 20h, 30h  ; Define 3 bytes at 3000h-3002h
DATA2 DW 4567h          ; Define a word at 3003h-3004h
COUNT EQU 3             ; COUNT = 3
START:
    LXI H, DATA1        ; Load HL with address of DATA1
    MOV A, M            ; Load A with first byte (10h)
    INR A               ; Increment A (A = 11h)
    STA 3005h           ; Store result at 3005h
    HLT                 ; Halt

2. Directives: Defining Data and Program Structure

Directives are non-executable commands that guide the assembler. They define memory layout, constants, and program structure.

Common Directives

Directive Purpose Example
DB Define Byte(s) DB 1, 2, 3
DW Define Word(s) DW 1234h
DS Reserve space (uninitialized) DS 10 (reserves 10 bytes)
EQU Define constant MAX EQU 100
ORG Set program origin ORG 2000h
END End of program END START

Example: Defining an Array and Looping Through It

ORG 4000h
ARRAY DB 5, 10, 15, 20, 25  ; Array of 5 bytes
SIZE EQU 5                   ; Size of array
SUM DB 0                     ; Variable to store sum
START:
    LXI H, ARRAY             ; HL = address of ARRAY
    MVI B, SIZE              ; B = 5 (counter)
    MVI C, 0                 ; C = 0 (sum accumulator)
LOOP:
    MOV A, M                 ; Load current byte into A
    ADD C                   ; Add to sum (C = C + A)
    MOV C, A                 ; Store sum back in C
    INX H                   ; Move to next byte
    DCR B                   ; Decrement counter
    JNZ LOOP                 ; Repeat if B != 0
    STA SUM                  ; Store final sum in SUM
    HLT
100201302403504HL (start)HL + 4 (end)
Array in memory (5 elements, 1 byte each, addressed via HL).

3. Instruction Set: Data Transfer and Arithmetic

A. Data Transfer Instructions

Instruction Operation Example
MOV Move data between registers/memory MOV A, B (A = B)
LXI Load 16-bit immediate into HL/BC/DE LXI H, 2000h (HL = 2000h)
LHLD Load 16-bit from memory into HL LHLD 2000h (HL = [2000h])
SHLD Store HL into memory SHLD 2000h ([2000h] = HL)
STA Store A into memory STA 2000h ([2000h] = A)
LDA Load A from memory LDA 2000h (A = [2000h])

B. Arithmetic and Logic Instructions

Instruction Operation Example
ADD Add to A ADD B (A = A + B)
SUB Subtract from A SUB C (A = A - C)
INR Increment register/memory INR B (B = B + 1)
DCR Decrement register/memory DCR C (C = C - 1)
DAA Decimal Adjust A (BCD correction) ADD B; DAA
CMP Compare A with operand CMP D (sets flags)

Worked Example: Sum of an Array (8085)

Problem: Calculate the sum of 10 bytes stored at 6000h and store the result at 6010h.

ORG 6000h
DATA DB 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
SUM DB 0
ORG 6020h
START:
    LXI H, DATA      ; HL = 6000h (start of array)
    MVI B, 10         ; Counter = 10
    MVI C, 0          ; Sum accumulator = 0
LOOP:
    MOV A, M          ; A = current byte
    ADD C             ; C = C + A
    MOV C, A          ; Update sum
    INX H             ; Move to next byte
    DCR B             ; Decrement counter
    JNZ LOOP          ; Repeat if B != 0
    STA SUM           ; Store sum at 6010h
    HLT

Trace:

Step HL B C A Action
1 6000 10 0 1 A = [6000h] (1)
2 6001 10 1 2 C = 1 + 2 = 3
... ... ... ... ... ...
10 600Ah 0 55 - Loop ends, store 55

4. Control Flow: Loops and Conditional Jumps

A. Unconditional Jumps

  • JMP addr: Jump to addr.
  • CALL addr: Call subroutine at addr (pushes return address to stack).
  • RET: Return from subroutine (pops return address from stack).

B. Conditional Jumps (8085)

Instruction Condition Example
JNZ addr Jump if Zero flag = 0 CMP B; JNZ NOT_EQUAL
JZ addr Jump if Zero flag = 1 CMP B; JZ EQUAL
JC addr Jump if Carry flag = 1 SUB C; JC BORROW
JNC addr Jump if Carry flag = 0 ADD B; JNC NO_OVERFLOW
DJNZ addr Decrement B, jump if B != 0 DJNZ LOOP

Example: Find Largest Element in an Array (8085)

Problem: Find the largest element in an array of 5 bytes starting at 4000h.

ORG 4000h
ARRAY DB 5, 10, 15, 20, 25
MAX DB 0
ORG 4010h
START:
    LXI H, ARRAY      ; HL = 4000h
    MVI B, 5          ; Counter = 5
    MOV A, M          ; A = first element (5)
    INX H             ; Move to next element
LOOP:
    CMP M             ; Compare A with current element
    JNC NEXT          ; If A >= M, skip update
    MOV A, M          ; Else, update max
NEXT:
    INX H             ; Move to next element
    DCR B             ; Decrement counter
    JNZ LOOP          ; Repeat if B != 0
    STA MAX           ; Store max at 400Ah
    HLT

Mermaid Diagram: Loop Flow

stateDiagram-v2
    [*] --> LOAD_FIRST: Load A with first element
    LOAD_FIRST --> INIT_COUNTER: B = 5
    INIT_COUNTER --> COMPARE: CMP M
    COMPARE --> UPDATE_MAX: If A < M, A = M
    UPDATE_MAX --> NEXT_ELEMENT: INX H
    NEXT_ELEMENT --> DECREMENT: DCR B
    DECREMENT --> CHECK_COUNTER: If B != 0, goto COMPARE
    CHECK_COUNTER --> [*]: Store A at MAX, HLT

5. String Manipulation

A. Defining Strings

ORG 5000h
STR1 DB 'HELLO'       ; Null-terminated string
STR2 DB 'WORLD', 0    ; Explicit null terminator
LEN EQU 5             ; Length of STR1

B. String Operations (8086 Example)

8086 has dedicated string instructions:

  • MOVSB: Move byte from DS:SI to ES:DI.
  • CMPSB: Compare bytes at DS:SI and ES:DI.
  • SCASB: Compare AL with byte at ES:DI.
  • STOSB: Store AL at ES:DI.

Example: Convert String to Uppercase (8086)

ORG 1000h
STR DB 'microprocessor is programmable', '$'
LEN EQU 35
ORG 1050h
START:
    LEA SI, STR       ; SI = offset of STR
    LEA DI, STR       ; DI = destination
    MOV CX, LEN       ; CX = length
UPCASE:
    MOV AL, [SI]      ; AL = current char
    CMP AL, 'a'       ; Check if lowercase
    JB NEXT           ; If < 'a', skip
    CMP AL, 'z'       ; Check if <= 'z'
    JA NEXT           ; If > 'z', skip
    SUB AL, 20h       ; Convert to uppercase (ASCII adjustment)
    MOV [DI], AL      ; Store back
NEXT:
    INC SI            ; Next character
    INC DI
    LOOP UPCASE       ; Repeat for CX times
    HLT

Mermaid Diagram: String Conversion Flow

sequenceDiagram
    participant SI as Source Index
    participant DI as Dest Index
    participant AL as Accumulator
    SI->>AL: Load [SI]
    AL->>AL: Check 'a' <= AL <= 'z'
    alt Lowercase?
        AL->>AL: AL = AL - 20h
        AL->>DI: Store [DI]
    end
    SI->>SI: INC SI
    DI->>DI: INC DI
    DI->>CX: LOOP (CX--)

6. Arithmetic Operations: Division and Multiplication

A. Division via Repeated Subtraction (8085)

; Divide 34h by 08h, store quotient in 8052h, remainder in 8050h
ORG 8000h
DIVIDEND DB 34h
DIVISOR DB 08h
QUOTIENT DB 0
REMAINDER DB 0
ORG 8020h
START:
    LDA DIVIDEND     ; A = 34h
    MVI B, 0         ; B = quotient (init to 0)
    MVI C, 0         ; C = remainder (init to 0)
LOOP:
    CMP DIVISOR      ; Compare A with divisor (08h)
    JC STORE          ; If A < divisor, store remainder
    SUB DIVISOR      ; A = A - 08h
    INR B            ; Quotient++
    JMP LOOP
STORE:
    MOV C, A         ; Remainder = A
    STA QUOTIENT     ; Store quotient
    MOV A, C         ; A = remainder
    STA REMAINDER    ; Store remainder
    HLT

Trace:

Step A B C Action
1 34h 0 0 34h >= 08h
2 2Ch 1 0 34h - 08h = 2Ch
3 24h 2 0 2Ch - 08h = 24h
4 1Ch 3 0 24h - 08h = 1Ch
5 14h 4 0 1Ch - 08h = 14h
6 0Ch 5 0 14h - 08h = 0Ch
7 04h 6 0 0Ch - 08h = 04h
8 04h 6 0 04h < 08h → exit
9 - - 04h Remainder = 04h

B. Multiplication via Repeated Addition (8085)

; Multiply 05h by 03h, store result in 8050h
ORG 8000h
MULTIPLICAND DB 05h
MULTIPLIER DB 03h
PRODUCT DB 0
ORG 8020h
START:
    LDA MULTIPLICAND ; A = 05h
    MVI B, 0         ; B = multiplier (03h)
    MVI C, 0         ; C = product (init to 0)
LOOP:
    MOV D, A         ; D = multiplicand (05h)
    ADD C            ; C = C + 05h
    MOV C, A         ; Update product
    DCR B            ; Decrement multiplier
    JNZ LOOP         ; Repeat if B != 0
    STA PRODUCT      ; Store product
    HLT

Trace:

Step A B C Action
1 05h 3 0 C = 0 + 05h = 05h
2 05h 2 05h C = 05h + 05h = 0Ah
3 05h 1 0Ah C = 0Ah + 05h = 0Fh
4 05h 0 0Fh B = 0 → exit

7. Stack Operations: PUSH and POP

The stack is a LIFO (Last-In-First-Out) memory area pointed to by the Stack Pointer (SP). It stores return addresses and temporary data.

Example: Using Stack for Subroutine

ORG 2000h
MAIN:
    CALL SUBROUTINE  ; Pushes return address to stack
    HLT
SUBROUTINE:
    PUSH B           ; Save B to stack
    PUSH C           ; Save C to stack
    ; Subroutine code here
    POP C            ; Restore C
    POP B            ; Restore B
    RET              ; Pops return address and jumps to MAIN

Mermaid Diagram: Stack Operations

sequenceDiagram
    participant SP as Stack Pointer
    participant MAIN as Main Program
    participant SUB as Subroutine
    MAIN->>SP: CALL SUB (pushes return addr)
    SUB->>SP: PUSH B (decrements SP, stores B)
    SUB->>SP: PUSH C (decrements SP, stores C)
    SUB->>SP: POP C (loads C, increments SP)
    SUB->>SP: POP B (loads B, increments SP)
    SUB->>SP: RET (pops return addr, jumps to MAIN)

8. Practical Example: Factorial Calculation (8085)

Problem: Calculate 5! (5 factorial) and store the result at 8050h.

ORG 8000h
NUM DB 5            ; Input number
FACT DB 1           ; Initialize factorial = 1
ORG 8020h
START:
    LDA NUM          ; A = 5
    MVI B, 1         ; Counter = 1
LOOP:
    MOV C, A         ; C = current value of A
    MVI D, 0         ; D = 0 (for multiplication)
MULT_LOOP:
    ADD C            ; D = D + C
    INR D            ; Increment counter (D)
    CMP B            ; Compare with counter
    JNZ MULT_LOOP    ; Repeat until B times
    MOV A, D         ; A = result of multiplication
    MOV FACT, A      ; Store intermediate result
    INR B            ; Increment counter
    CMP NUM          ; Compare with original number
    JNZ LOOP         ; Repeat until B = 5
    HLT

Trace for 5!:

Iteration A (Input) B (Counter) FACT (Result)
1 5 1 1
2 5 2 1 * 2 = 2
3 5 3 2 * 3 = 6
4 5 4 6 * 4 = 24
5 5 5 24 * 5 = 120

In the Real World

  1. eSewa and Kathmandu Traffic Management

    • Idea Used: Interrupts and Priority Handling
    • How: eSewa processes thousands of transactions per second. The system uses interrupt-driven programming to handle real-time payments. When a user submits a payment request, an interrupt is triggered, and the microprocessor prioritizes the transaction (e.g., electricity bill payment) over less urgent tasks like updating user profiles. The 8085-style RST (Restart) interrupts are used to jump to specific service routines.
    • Example: During peak hours, the system may use nested interrupts where a high-priority payment interrupt (RST 7) preempts a lower-priority profile update interrupt (RST 5).
  2. Pathao’s Ride Allocation Algorithm

    • Idea Used: Stack and Queue Management
    • How: Pathao’s backend uses stacks (LIFO) to manage driver availability and queues (FIFO) to allocate rides. When a user requests a ride, the system:
      1. Pushes the user’s location onto a queue (first-come-first-served).
      2. Uses a stack to pop the nearest available driver (last driver to become available is matched first).
    • Assembly Analogy: The PUSH/POP instructions in 8085 are analogous to how Pathao’s algorithm pushes/pops driver IDs from a stack to ensure optimal matching.
  3. NTC’s Network Packet Routing

    • Idea Used: Memory Addressing and Data Transfer
    • How: The Nepal Telecommunications Corporation (NTC) routes data packets using segmented memory addressing (similar to 8086’s CS:IP or DS:SI). When a packet arrives:
      • The source IP is loaded into a register (e.g., SI in 8086).
      • The destination IP is compared using CMPSB (compare string bytes).
      • The packet is then transferred using MOVSB (move string byte) to the appropriate output buffer.
    • Example: If a packet from 192.168.1.1 is destined for 192.168.1.100, the microprocessor loads the source IP into SI, the destination into DI, and uses REP MOVSB to copy the packet data.
  4. Khalti’s Transaction Logging

    • Idea Used: Looping and Array Manipulation
    • How: Khalti logs every transaction in a circular buffer (array) stored in memory. For each transaction:
      • A loop (DJNZ in 8085 or LOOP in 8086) iterates through the buffer to find an empty slot.
      • The transaction details (amount, timestamp, user ID) are stored using STA (store A) or MOVSB.
      • The buffer wraps around using modular arithmetic (e.g., INX H; CPI MAX_SIZE; JNZ NEXT).
    • Example: If the buffer is 100 transactions long, Khalti’s system might use:
      LXI H, BUFFER_START
      MVI B, 100          ; Buffer size
      LOOP:
          CMP M            ; Check if slot is empty (e.g., M = 0)
          JNZ FULL         ; If not empty, try next
          ; Store transaction data here
          INX H            ; Move to next slot
          DCR B            ; Decrement counter
          JNZ LOOP          ; Repeat
      

Exam Tip

  1. Understand the Difference Between Directives and Instructions:

    • Directives (DB, DW, EQU) are for the assembler and do not generate machine code.
    • Instructions (MOV, ADD, JMP) are executed by the microprocessor.
    • Exam Pitfall: Many students confuse DB (define byte) with MOV (move). Always check whether the question asks for data definition or execution.
  2. Master the 8085 vs. 8086 Syntax:

    • 8085: Uses 8-bit registers (A, B, C) and 16-bit registers (HL, BC, DE). Example:
      MVI B, 10   ; Move immediate to B
      
    • 8086: Uses 16-bit registers (AX, BX, CX). Example:
      MOV BL, 10  ; Move immediate to BL
      
    • Exam Tip: Always declare ORG and use the correct register set for the microprocessor in the question.
  3. Loop Structures Are High-Weightage:

    • 8085: Use DJNZ (decrement and jump if not zero) for loops.
      MVI B, 5    ; Counter = 5
      LOOP:
          ; Loop body
          DCR B     ; Decrement counter
          JNZ LOOP  ; Jump if B != 0
      
    • 8086: Use LOOP (decrements CX and jumps if CX != 0).
      MOV CX, 5   ; Counter = 5
      LOOP:
          ; Loop body
          LOOP LOOP ; Decrement CX, jump if CX != 0
      
    • Exam Pitfall: Forgetting to initialize the counter or misusing JNZ/LOOP can lead to infinite loops.
  4. String Manipulation in 8086:

    • Key Instructions: MOVSB, CMPSB, SCASB, STOSB.
    • Prefixes:
      • REP: Repeat while CX != 0.
      • REPE/REPZ: Repeat while CX != 0 and ZF = 1.
      • REPNE/REPNZ: Repeat while CX != 0 and ZF = 0.
    • Example: To copy a string:
      LEA SI, SOURCE
      LEA DI, DEST
      MOV CX, LENGTH
      REP MOVSB
      
  5. Arithmetic Operations:

    • Division: Always check for division by zero (e.g., CMP B; JZ DIV_ZERO).
    • Multiplication: Use repeated addition (as shown in the factorial example).
    • BCD Adjustment: After ADD/SUB, use DAA (8085) to correct BCD results.
      MVI A, 99h
      MVI B, 01h
      ADD B
      DAA          ; Adjusts A to 00h (99h + 01h = 100h in BCD)
      
  6. Stack Operations:

    • PUSH/POP: Always save and restore registers before/after a subroutine call.
      PUSH B       ; Save B
      PUSH C       ; Save C
      CALL SUBROUTINE
      POP C        ; Restore C
      POP B        ; Restore B
      
    • Exam Tip: Questions often ask to "preserve the stack" or "avoid stack overflow." Ensure you manage SP correctly.
  7. Worked Examples Are Your Best Friend:

    • Past Exam Pattern: 60% of questions ask for complete programs (e.g., sum of array, string reversal, factorial). Always:
      1. Define data (DB, DW).
      2. Initialize registers (LXI, MVI).
      3. Use loops (DJNZ, LOOP).
      4. Handle edge cases (e.g., empty array, division by zero).
    • Template for Array Problems:
      ORG START_ADDR
      ARRAY DB ...    ; Define array
      SIZE EQU ...    ; Define size
      START:
          LXI H, ARRAY ; Load array address
          MVI B, SIZE  ; Load counter
          ; Loop logic here
          HLT
      
  8. Common Mistakes to Avoid:

    • Incorrect Addressing: Forgetting to increment HL/SI/DI in loops leads to infinite loops or overwriting data.
    • Flag Misuse: Ignoring CY (carry) or Z (zero) flags in conditional jumps.
    • Register Clobbering: Overwriting registers used by the loop (e.g., using B as a counter but also in arithmetic).

8085/8086 CPU CoreGeneral-Purpose (AX,BX,CX,DX)RegistersSegment (CS,DS,SS,ES)ALUFlags (Z,S,CY,...)Control Unit
Key components of an 8085/8086 microprocessor (simplified).

Based on the TU BSc CSIT syllabus for Microprocessor (CSC167), unit 8.

Discussion

Loading…