8085 Program to Find the Sum of Array Elements
Write an 8085 assembly program that calculates the sum of N 8-bit numbers stored in memory.
-
Input:
2500H
= number of elements (N)2501H
to2500H + N
= data values
-
Output:
3000H
= lower 8 bits of the result (sum)3001H
= carry flag (0 or 1)
⚡ TL;DR — Final Working Code
Section titled “⚡ TL;DR — Final Working Code” ARRAY_BASE EQU 2500H ; Input: [2500H] = count, [2501H...] = data RESULT_LO EQU 3000H ; Output: 8-bit sum RESULT_HI EQU 3001H ; Output: carry
LXI H, ARRAY_BASE ; HL → array start MOV C, M ; C ← count INX H ; HL → first data element
MVI A, 00H ; A ← running sum MVI B, 00H ; B ← carry tracker
LOOP: ADD M ; A ← A + [HL] JNC SKIP ; If no carry, skip INR B ; Else, B ← B + 1
SKIP: INX H ; HL → next element DCR C ; C ← C - 1 JNZ LOOP
STA RESULT_LO ; Store sum MOV A, B STA RESULT_HI ; Store carry HLT
🧱 Step 1: Define the Interface
Section titled “🧱 Step 1: Define the Interface”Before we do anything, we need to define how the outside world communicates with this program.
Every working program needs a working interface.
This interface tells us:
- Where to read inputs from
- Where to place the output
📦 The Interface We’ll Use
Section titled “📦 The Interface We’ll Use”We’ll use memory locations to read and write data:
Address | Meaning |
---|---|
2500H | Number of elements (N) |
2501H | First element |
… | Next N-1 elements |
3000H | Output: 8-bit result (sum) |
3001H | Output: Carry (0 or 1) |
This ensures:
- The array is self-describing
- The output is stored clearly and separately
- You can verify the result without checking flags
🧠 Why This Is a Good Interface
Section titled “🧠 Why This Is a Good Interface”- Count-first layout supports dynamic-sized arrays
- Output address is predictable and external — doesn’t overwrite input
- Handles overflow explicitly — no hidden flag checking required
❌ Bad Interface Examples
Section titled “❌ Bad Interface Examples”- Putting the sum back into the first array element (overwrites data)
- Using the carry flag without storing it (not visible after program halts)
- Hardcoding the array size in the program instead of reading it
🧾 Code (Read Count Only)
Section titled “🧾 Code (Read Count Only)”Let’s just begin by reading the count — a foundational step for any loop.
LXI H, 2500H ; HL → start of arrayMOV C, M ; C ← number of elementsHLT ; Pause to inspect C
🧪 Manual Test
Section titled “🧪 Manual Test”Set memory:
2500H = 04H
Expected:
- Register
C
should contain04H
This confirms the input interface is working.
🧱 Step 2: Sum the First Element
Section titled “🧱 Step 2: Sum the First Element”Now that we’ve read how many elements we need to add, it’s time to:
Begin adding elements one by one using the accumulator.
We’ll start small — by adding just the first element and observing the result.
💡 What We’re Doing
Section titled “💡 What We’re Doing”- Move HL to the first element (
2501H
) - Initialize accumulator
A
with 0 - Add the value at
HL
toA
We’ll also leave space in register B
for the carry bit (in case we eventually exceed FFH
).
🧠 Why One Element?
Section titled “🧠 Why One Element?”Doing one addition first helps us:
- Validate that we’re loading values correctly
- See how the
ADD
instruction affectsA
and the carry flag - Build the core pattern for the loop safely
🧾 Code So Far
Section titled “🧾 Code So Far”LXI H, 2500H ; HL → start of arrayMOV C, M ; C ← number of elementsINX H ; HL → first element
MVI A, 00H ; A ← 0 (sum)ADD M ; A ← A + [HL]HLT ; Check result
🧪 Manual Test
Section titled “🧪 Manual Test”Set memory:
2500H = 03H2501H = 2AH
Expected:
- Register
A
=2AH
- Carry flag not set
Now try:
2501H = FFH
Expected:
- Register
A
=FFH
- Carry flag = 0
Later, if we add more and exceed FFH
, carry will become important.
🧠 Tip: Why Start with A = 00H?
Section titled “🧠 Tip: Why Start with A = 00H?”This lets us treat the sum like a growing total, building up from 0 — similar to how accumulators work in most languages and CPUs.
🧱 Step 3: Loop Through All Elements
Section titled “🧱 Step 3: Loop Through All Elements”We’ve added one element. Now it’s time to:
Loop through the rest of the array and keep adding each value to the accumulator.
We’ll also monitor the carry flag in each addition and track it separately, using register B
.
💡 What We’re Doing
Section titled “💡 What We’re Doing”-
Set accumulator
A
to 0 (for the sum) -
Set register
B
to 0 (for total carry) -
Loop through:
ADD M
to add current value toA
- If carry is set, increment
B
- Move to next element
- Decrease counter
C
-
End the loop when
C = 0
This gives us:
- 8-bit sum in
A
- Carry count in
B
(will be 1 for simple cases)
🧾 Full Code So Far
Section titled “🧾 Full Code So Far” LXI H, 2500H ; HL → base address MOV C, M ; C ← count INX H ; HL → first element
MVI A, 00H ; Accumulator for sum MVI B, 00H ; Carry tracker
LOOP: ADD M ; A ← A + [HL] JNC SKIP ; If no carry, skip incrementing B INR B ; Else, increment carry count
SKIP: INX H ; Move to next element DCR C ; Decrease counter JNZ LOOP ; Repeat if elements remain
HLT ; Inspect A and B
🧪 Manual Test
Section titled “🧪 Manual Test”Set memory:
2500H = 03H2501H = 20H2502H = 90H2503H = F0H
Manual addition:
- 20H + 90H = B0H → no carry
- B0H + F0H = 0AH (carry out)
Expected:
- Register
A
=0AH
- Register
B
=01H
🧠 Tip: Why Track Carry Separately?
Section titled “🧠 Tip: Why Track Carry Separately?”8085 only gives us 8-bit math, but the real sum may be larger than 255. By tracking the carry, we simulate 16-bit addition using two registers.
🧱 Step 4: Store the Result in Memory
Section titled “🧱 Step 4: Store the Result in Memory”We now have:
- The 8-bit sum in register
A
- The carry count in register
B
(either00H
or01H
for small arrays)
Our task is to:
Store the final result to predefined output addresses so the rest of the system (or a human) can see the outcome.
💡 What We’re Doing
Section titled “💡 What We’re Doing”- Store the value of
A
(sum) at3000H
- Store the value of
B
(carry) at3001H
This gives us a two-byte result:
- Low byte =
A
- High byte =
B
(which will be 00H or 01H)
Together, they represent the true 16-bit sum:
Result = B × 256 + A
🧾 Final Code (So Far)
Section titled “🧾 Final Code (So Far)” ARRAY_BASE EQU 2500H RESULT_LO EQU 3000H RESULT_HI EQU 3001H
LXI H, ARRAY_BASE MOV C, M INX H
MVI A, 00H MVI B, 00H
LOOP: ADD M JNC SKIP INR B
SKIP: INX H DCR C JNZ LOOP
STA RESULT_LO ; Store sum (A) MOV A, B STA RESULT_HI ; Store carry (B) HLT
🧪 Manual Test
Section titled “🧪 Manual Test”Set memory:
2500H = 03H2501H = 20H2502H = 90H2503H = F0H
Expected memory after execution:
3000H = 0AH ; Low byte of sum3001H = 01H ; High byte of sum (carry)
🧠 Takeaway
Section titled “🧠 Takeaway”This is a classic 8-bit-to-16-bit pattern in 8085:
- Work within 8-bit constraints
- Track overflow manually
- Store results explicitly
🧱 Step 5: Refactor and Clean Up
Section titled “🧱 Step 5: Refactor and Clean Up”We’ve built a fully working program to compute the sum of an array, including carry. Now it’s time to refactor — to make the program clearer, more maintainable, and easier to reuse.
🧠 Why Refactor?
Section titled “🧠 Why Refactor?”We already have a correct solution. But refactoring improves:
- Readability for humans
- Adaptability for future changes
- Professionalism in design
🔧 What We’ll Improve
Section titled “🔧 What We’ll Improve”✅ 1. Use EQU
to Name Addresses
Section titled “✅ 1. Use EQU to Name Addresses”No more magic numbers. Let’s define constants for:
- Input base
- Output locations
✅ 2. Add Comments That Explain Why, Not Just What
Section titled “✅ 2. Add Comments That Explain Why, Not Just What”Good comments explain purpose, not just syntax.
🧾 Refactored Code
Section titled “🧾 Refactored Code” ; Interface definitions ARRAY_BASE EQU 2500H ; Start of array (first byte = count) RESULT_LO EQU 3000H ; Store sum (8-bit) RESULT_HI EQU 3001H ; Store carry (if any)
; Step 1: Load count LXI H, ARRAY_BASE ; HL → start of array MOV C, M ; C ← number of elements INX H ; HL → first data element
; Step 2: Initialize accumulators MVI A, 00H ; A ← running sum MVI B, 00H ; B ← carry tracker
LOOP: ADD M ; Add current element to A JNC SKIP ; If no carry, skip increment INR B ; Else increment carry
SKIP: INX H ; HL → next element DCR C ; C ← C - 1 JNZ LOOP ; Repeat if more elements
; Step 3: Store result STA RESULT_LO ; Store low byte of sum MOV A, B STA RESULT_HI ; Store high byte (carry) HLT
✅ What This Achieves
Section titled “✅ What This Achieves”- Makes intent visible:
ARRAY_BASE
,RESULT_LO
, etc., are meaningful - Keeps the logic easy to modify (e.g., changing output address)
- Provides a clean separation of input, processing, and output
📚 Summary
Section titled “📚 Summary”This problem is simple, but powerful. It teaches:
- How to design a clean interface for variable-length input and fixed output
- How to use the accumulator pattern in assembly
- How to manage overflow manually by tracking the carry flag
- How to structure loops and conditionals using only
ADD
,JNC
,INX
, andDCR
- The importance of refactoring — turning a working solution into a readable one
Together, these steps build a strong foundation for more advanced operations like:
- 16-bit additions
- Multi-word arithmetic
- Array-level analytics