0

I'm an amateur in assembly and one of my assignments is to do a fibonacci sequence based on my user input. So if my user input is 5, the output will go like this 0 1 1 2 3 It is being placed in an array and then the index increases and some arithmetic operation is done to achieve the sequence. The user input is limited to 25, so if user input is to be 25, my output should appear like the above, all the way to the value of 46368. At first, I used al, bl and cl to do the arithmetic stuff, but realizing that 8 bit registers are too small, I changed to 16 bits.

At some point the number comes out as negative and i do understand that its like because of the sign bit and the number is a signed number how do i make everything unsigned? in a way i have already tried to do PRINT_UDEC but at some point of time the number goes back to a small number and doesn't keep adding up and i actually had the same thing happen when i was doing coding another program and i used al, which is an 8 bit register so i just changed it to a 16 bit register and it worked I tried changing it to 32 bits registers too but it still doesn't work! as far as i know(correct me if im wrong) the biggest value of ax can be up to 65536? and the 25th number of the fibonacci sequence is 46368 which is still within the range of a 16 bit register. how do i fix the overflow of this?

%include "io.inc"

section .bss
fibo    resb 26 * 4; reserve an array of 25 uninitialized bytes
userInput   resb 4 ; reserve 4 bytes for userInput

section .text
global _main
_main:
    mov ebp, esp ; entry point for correct debugging
    xor edx, edx ; initializing my secondary index to 0
    mov eax, 0 ; a = 0
    mov ebx, 1 ; b = 1
    mov ecx, 0 ; c = 0

    PRINT_STRING "Enter a number between 3 and 25 inclusively:" ;prompt user for integer input
    NEWLINE
    GET_DEC 4, userInput ; 

    mov edi, userInput ; 
    mov esi, fibo ; 
    call indexInc ; 
    mov edx, 0 ; 
    call printarray ; 

indexInc:
    mov [esi], eax ; moves the a = 0 in the first element of the array
    inc esi ; increases array index
    mov [esi], ebx ; moves the b = 1 in the second element of the array
    inc esi ; increases array index
    mov edx, 3 ; secondary pointer for comparison purposes

forloop:
    cmp edx, [userInput] ; 
    jg term ;
    add ecx, eax ; 
    add ecx, ebx ; 
    mov [esi], ecx ; 
    mov eax, ebx ; 
    mov ebx, ecx ; 
    xor ecx, ecx ; 
    inc esi ; increase array index
    inc edx ; increase secondary pointer
    jmp forloop ; 

printarray:
    cmp edx, [userInput] ; 
    je term ; 
    PRINT_DEC 1, [fibo + edx] ; 
    NEWLINE
    inc esi ; increase array index
    inc edx ; increase pointer
    jmp printarray ; 

term:
    ret ; terminate program
  • Not to be picky, but your code is using 32 bit registers, not 16 as you are saying. ;) What's the highest number you are seeing on the output before it goes negative? You need to show your output. – lurker Nov 09 '18 at 16:55
  • 2
    The problem might be that PRINT_DEC or PRINT_UDEC print out 16 bit values, instead of 32 bit values. See if there is a 32 bit version of the PRINT... function. For unsigned 32 bit registers, you should be able to go up to fib(47). – rcgldr Nov 09 '18 at 17:54

1 Answers1

2

Try using PRINT_DEC 4, [fibo + edx] or PRINT_UDEC 4, [fibo + edx].
Judging from this source.


Note that assembly lines don't have to terminate with a ; - that's the start of a comment.
Also your program flow and coding style are messy: don't share ret across functions unless you are golfing or exploiting some trick.
Jumping forward is harder to follow than jumping back - if possible prefer do {} while (); over while () {}.
Give the labels meaningful names and, if needed, adopt a naming convention that make function labels stand out.
You comments are goods.

I found it easier to follow assembly code (code in general) if it is spatially grouped in logical block - avoiding a wall-of-text effect.
You are zeroing registers in two different ways - that's strange at best (suspicious at worst).

I think you can perform a fibonacci step with just two instructions:

xchg eax, ebx
add ebx, eax

if eax is f(n-1) and ebx is f(n)

Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124