I am trying to build a Fibonacci sequence in a 6502 assembler. It needs at least one add function, a least one branch function, and at least one compare function. I know how to add and store integers, but I am confused by branch and compare functions.
Fibonnacci sequence in 6502 assembler
136 views Asked by Liam Knipper AtThere are 2 answers
On
but I am confused by branch and compare functions
In C code we might use a structured statement, here a while loop:
count = -n;
do {
// loop body
count++;
} while ( count != 0 );
// more code
whereas using what can be called if-goto-label, the same (still in C) :
count = -n;
Loop1:
// loop body
count++;
if ( count != 0 ) goto Loop1;
// more code
So, hopefully you see that these two constructions are equivalent and identical and will thus run the same, even though the latter is a bit more verbose. Both will run the same loop body for the same number of iterations.
The latter form, however, is much closer to assembly language, which also uses if-goto-label.
Key to assembly, then, is how the C-statement if ( count != 0 ) goto Loop1; is performed. The issue with an if-goto-label statement in C is that there are generally too many operands for the processor to work with in one machine code instruction (here, those operands are count, !=, 0, Loop1 and we can imagine each of those operands, in the general case, will need to vary.)
So, the solution in many instruction sets is to split the if-goto-label construct into two instructions by connecting them using condition codes. Here, the first is would be a compare of count and 0 that sets the condition codes, and the second is a branch using condition != and label target Loop1 that reads the condition codes.
These two instructions communicate via the condition codes, but you can read them as performing the if-goto-label construct via a two instruction sequence (here an extra instruction to clear the X register for the later cpx):
ldx #$0
cpx count
bne Loop1
the above is then the assembly pseudo-code translation for the C-based if-goto-label construct if ( count != 0 ) goto Loop1;.
Each processor's operation and assembly language varies a bit, so one general idea that works well is to:
- write algorithms in terms of control structures using C structured statements
- translate control structures to if-goto-label form, still in C
- translate if-goto-label statements to specific assembly

I assume you are limited to using the instructions mentioned in the table. So you have
CPXand you haveBNE.CPXcompares the content of theXregister with its operand. It does this by subtracting the operand fromXand then setting some flags accordingly.The 6502 has a status register containing a number of flags i.e. one bit values which represent "true" or "false". The flags are:
$01and you doCPX #$03the result would be$fewhich is -2 in 2's completement and theNflag will be set.CPX #$01would setZifXcontains 1, or clearZifXcontains any other value.CPXit will be set if X is greater than the operand (interpreting both as unsigned).CPX #1will setCfor any value inXexcept 0 or 1.There are several other flags, but we can ignore them because they are unaffected by
CPX.The branches in the 6502 work by inspecting one of the flags and then performing the jump, or not performing the jump depending on its value. There are two branches associated with each flag, one to jump if the flag is set and one to jump if the flag is clear.
For the C flag we have:
BCSjump if the carry flag is setBCCjump if the carry flag is clearFor the N flag we have:
BMIjump if the negative flag is setBPLjump if the negative flag is clearThe "MI" stands for "minus" and the "PL" stands for "plus"
For the Z flag, we have:
BEQjump if the zero flag is setBNEjump if the zero flag is clear"EQ" means "equal to zero" and "NE" means "not equal to zero". These two opcodes could have been
BZSandBZCrespectively.So, restricting yourself to the instructions in your list, If you have a loop counter at address
loopCounterand the number of times you want to loop at addressmaxCountyou could implement your loop as follows.Note that the above always executes the loop code at least once and setting
maxCountto zero will cause the loop to execute 256 times.If you have the full 6502 instruction set you can make the above loop much more efficient. Even with just the
DEXinstruction (decrement X) you can store the count inXand count downwards.DEXis much faster thanINCandDEXalso affects theZflag, so you don't need theCPX.Addendum:
Not relevant to the question but I can't resist this, but the 14th Fibonacci number is 377 which doesn't fit in eight bits. If you want a really fast way to calculate any Fibonacci number that does fit in 8 bits, you can just do a lookup.