This blog post will walk you through an 8086 assembly program designed to generate the Fibonacci sequence. While this may sound simple, it’s an excellent example for understanding looping, arithmetic operations, and register management in assembly language.
The Fibonacci Series
The Fibonacci series is a sequence where each number is the sum of the two preceding ones:
0, 1, 1, 2, 3, 5, 8, 13, 21, …
In this program, we’ll generate the first 10 Fibonacci numbers and store them in memory.
Code
; 8086 Program to Generate 10 Fibonacci Numbers
data segment
COUNT equ 10 ; Number of terms to generate
FIB_SERIES db COUNT dup(?) ; Array to store the series
data ends
code segment
assume cs:code, ds:data
start:
; Initialize Data Segment (DS) register
mov ax, data
mov ds, ax
; Use SI as a pointer to the array
mov si, offset FIB_SERIES
; Seed the first two Fibonacci numbers
; Fib(0) = 0
mov byte ptr [si], 00h
; Fib(1) = 1
inc si
mov byte ptr [si], 01h
; Set up loop counter. We already have 2 numbers,
; so we need to generate (COUNT - 2) more.
mov cx, COUNT
sub cx, 2
L1:
; AL = Fib(n-1) (e.g., [si])
mov al, [si]
; BL = Fib(n-2) (e.g., [si-1])
mov bl, [si-1]
; AL = Fib(n-1) + Fib(n-2)
add al, bl
; Move pointer to next position Fib(n)
inc si
; Store the new term: [si] = AL
mov [si], al
; Decrement CX, loop if CX is not zero
loop L1
; Halt execution for debugging
int 3
code ends
end start
Understanding the Code
The program is similarly divided into a data segment and a code segment.
Data Segment
data segment: This section defines our variables and constants.COUNT equ 10:equ(equate) sets up a constant namedCOUNTwith the value 10. This makes the code easier to read and modify.FIB_SERIES db COUNT dup(?): This is the core of our data.dbstands for Define Byte.COUNT dup(?)tells the assembler to duplicate an uninitialized byte (?)COUNT(10) times. This reserves 10 bytes of memory to store our sequence.
Code Segment
code segment: This section contains the program instructions.assume cs:code, ds:data: Tells the assembler our segment registers.start:: The program’s entry point.mov ax, data/mov ds, ax: This is the standard procedure to initialize theds(Data Segment) register so we can access our variables in thedata segment.mov si, offset FIB_SERIES: We load the starting address (oroffset) of our arrayFIB_SERIESinto thesi(Source Index) register.siwill act as our pointer, keeping track of where we are in the array.mov byte ptr [si], 00h: This “seeds” the first number.[si]means “the memory location pointed to bysi“. We store00h(Fibonacci(0)) at the first position in the array.inc si: We increment thesipointer to move to the next byte in the array.mov byte ptr [si], 01h: We seed the second number, storing01h(Fibonacci(1)) at the second position.mov cx, COUNT/sub cx, 2: We set up our loop. Thecxregister is the standard loop counter. Since we’ve already generated the first two numbers, we subtract 2 from the totalCOUNT.cxis now 8.L1:: This is a label that marks the beginning of our loop.mov al, [si]: Loads the (n-1)th term (the onesiis currently pointing to) into thealregister.mov bl, [si-1]: Loads the (n-2)th term (the one beforesi) into theblregister.add al, bl: This is the Fibonacci logic. It adds the previous two terms, and the result (the new term) is stored inal.inc si: We advance our pointer to the next empty spot in the array.mov [si], al: We store the new term (fromal) into the array at the newsiposition.loop L1: This is a powerful instruction. It automatically decrementscxby 1 and, ifcxis not yet zero, jumps back to theL1label. This will repeat 8 times.int 3: The breakpoint instruction halts execution so we can check our results in the debugger.
High-Level Overview
- Data Initialization: A constant
COUNTis set to 10. A byte array namedFIB_SERIESis reserved for 10 bytes. - Segment Setup: The
dsregister is pointed to the data segment. - Pointer & Seeding: The
siregister is pointed to the start ofFIB_SERIES. The first two bytes of the array are set to00hand01h. - Loop Setup: The loop counter
cxis set to8(10 – 2). - Calculation Loop (Repeats 8 times):
- Get the (n-1)th and (n-2)th terms from memory.
- Add them together.
- Advance the memory pointer.
- Store the new result in the array.
- Program Termination: The
loopinstruction finishes whencxreaches zero, and the program halts atint 3.
Output
C:\TASM>masm fibo.asm
Microsoft (R) Macro Assembler Version 5.00
Copyright (C)...
0 Warning Errors
0 Severe Errors
C:\TASM>link fibo.obj
C:\TASM>debug fibo.exe
-g
AX=0000 BX=0001 CX=0000 DX=0000 SI=000A ...
DS=0B97 CS=0B98 IP=0018
0B98:0018 CC INT 3
-d 0B97:0000
0B97:0000 00 01 01 02 03 05 08 0D-15 22 00 00 00 00 00 00 ........".......
Understanding the Memory Dump
0B97:0000 00 01 01 02 03 05 08 0D 15 22
Here’s what’s stored in memory:
| Index | Value (Hex) | Decimal |
|---|---|---|
| 1 | 00 | 0 |
| 2 | 01 | 1 |
| 3 | 01 | 1 |
| 4 | 02 | 2 |
| 5 | 03 | 3 |
| 6 | 05 | 5 |
| 7 | 08 | 8 |
| 8 | 0D | 13 |
| 9 | 15 | 21 |
| 10 | 22 | 34 |
These are the first ten Fibonacci numbers correctly generated and stored in memory.
Generating the Fibonacci sequence in 8086 assembly turns abstract math into concrete data 🔢, one byte at a time. It’s a perfect example of how loops and pointers work together to build complex data structures 💻.