8086 Assembly Program to Generate the Fibonacci Sequence

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 named COUNT with the value 10. This makes the code easier to read and modify.
  • FIB_SERIES db COUNT dup(?): This is the core of our data.
    • db stands 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 the ds (Data Segment) register so we can access our variables in the data segment.
  • mov si, offset FIB_SERIES: We load the starting address (or offset) of our array FIB_SERIES into the si (Source Index) register. si will 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 by si“. We store 00h (Fibonacci(0)) at the first position in the array.
  • inc si: We increment the si pointer to move to the next byte in the array.
  • mov byte ptr [si], 01h: We seed the second number, storing 01h (Fibonacci(1)) at the second position.
  • mov cx, COUNT / sub cx, 2: We set up our loop. The cx register is the standard loop counter. Since we’ve already generated the first two numbers, we subtract 2 from the total COUNT. cx is now 8.
  • L1:: This is a label that marks the beginning of our loop.
  • mov al, [si]: Loads the (n-1)th term (the one si is currently pointing to) into the al register.
  • mov bl, [si-1]: Loads the (n-2)th term (the one before si) into the bl register.
  • add al, bl: This is the Fibonacci logic. It adds the previous two terms, and the result (the new term) is stored in al.
  • inc si: We advance our pointer to the next empty spot in the array.
  • mov [si], al: We store the new term (from al) into the array at the new si position.
  • loop L1: This is a powerful instruction. It automatically decrements cx by 1 and, if cx is not yet zero, jumps back to the L1 label. This will repeat 8 times.
  • int 3: The breakpoint instruction halts execution so we can check our results in the debugger.

High-Level Overview

  1. Data Initialization: A constant COUNT is set to 10. A byte array named FIB_SERIES is reserved for 10 bytes.
  2. Segment Setup: The ds register is pointed to the data segment.
  3. Pointer & Seeding: The si register is pointed to the start of FIB_SERIES. The first two bytes of the array are set to 00h and 01h.
  4. Loop Setup: The loop counter cx is set to 8 (10 – 2).
  5. 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.
  6. Program Termination: The loop instruction finishes when cx reaches zero, and the program halts at int 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:

IndexValue (Hex)Decimal
1000
2011
3011
4022
5033
6055
7088
80D13
91521
102234

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 💻.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.