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) orLOOP(8086) for iterative tasks, with careful register management to avoid infinite loops. - String Manipulation: Directives like
DBdefine strings, while instructions likeMOVSB(8086) orLXI H+MOV M(8085) process them. - Arithmetic Logic: Master division/multiplication via repeated addition/subtraction (e.g.,
DCR,INR) and useDAA(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
- Directives: Instructions for the assembler (not the microprocessor).
DB(Define Byte): Stores 8-bit data.DB 5Ah, 0FFh ; Defines two bytes: 5Ah and FFhDW(Define Word): Stores 16-bit data.DW 1234h ; Defines a 16-bit wordEQU: Assigns a constant value.COUNT EQU 10 ; COUNT = 10ORG: Sets the origin (starting address) of the program.ORG 2000h ; Program starts at 2000h
- 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.
- Data Transfer:
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
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 toaddr.CALL addr: Call subroutine ataddr(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, HLT5. 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 fromDS:SItoES:DI.CMPSB: Compare bytes atDS:SIandES:DI.SCASB: CompareALwith byte atES:DI.STOSB: StoreALatES: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
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-styleRST(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).
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:
- Pushes the user’s location onto a queue (first-come-first-served).
- Uses a stack to pop the nearest available driver (last driver to become available is matched first).
- Assembly Analogy: The
PUSH/POPinstructions in 8085 are analogous to how Pathao’s algorithm pushes/pops driver IDs from a stack to ensure optimal matching.
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:IPorDS:SI). When a packet arrives:- The source IP is loaded into a register (e.g.,
SIin 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.
- The source IP is loaded into a register (e.g.,
- Example: If a packet from
192.168.1.1is destined for192.168.1.100, the microprocessor loads the source IP intoSI, the destination intoDI, and usesREP MOVSBto copy the packet data.
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 (
DJNZin 8085 orLOOPin 8086) iterates through the buffer to find an empty slot. - The transaction details (amount, timestamp, user ID) are stored using
STA(store A) orMOVSB. - The buffer wraps around using modular arithmetic (e.g.,
INX H; CPI MAX_SIZE; JNZ NEXT).
- A loop (
- 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
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) withMOV(move). Always check whether the question asks for data definition or execution.
- Directives (
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
ORGand use the correct register set for the microprocessor in the question.
- 8085: Uses 8-bit registers (
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(decrementsCXand jumps ifCX != 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/LOOPcan lead to infinite loops.
- 8085: Use
String Manipulation in 8086:
- Key Instructions:
MOVSB,CMPSB,SCASB,STOSB. - Prefixes:
REP: Repeat whileCX != 0.REPE/REPZ: Repeat whileCX != 0andZF = 1.REPNE/REPNZ: Repeat whileCX != 0andZF = 0.
- Example: To copy a string:
LEA SI, SOURCE LEA DI, DEST MOV CX, LENGTH REP MOVSB
- Key Instructions:
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, useDAA(8085) to correct BCD results.MVI A, 99h MVI B, 01h ADD B DAA ; Adjusts A to 00h (99h + 01h = 100h in BCD)
- Division: Always check for division by zero (e.g.,
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
SPcorrectly.
- PUSH/POP: Always save and restore registers before/after a subroutine call.
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:
- Define data (
DB,DW). - Initialize registers (
LXI,MVI). - Use loops (
DJNZ,LOOP). - Handle edge cases (e.g., empty array, division by zero).
- Define data (
- 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
- Past Exam Pattern: 60% of questions ask for complete programs (e.g., sum of array, string reversal, factorial). Always:
Common Mistakes to Avoid:
- Incorrect Addressing: Forgetting to increment
HL/SI/DIin loops leads to infinite loops or overwriting data. - Flag Misuse: Ignoring
CY(carry) orZ(zero) flags in conditional jumps. - Register Clobbering: Overwriting registers used by the loop (e.g., using
Bas a counter but also in arithmetic).
- Incorrect Addressing: Forgetting to increment
Based on the TU BSc CSIT syllabus for Microprocessor (CSC167), unit 8.
Discussion
Loading…