0

I am using x86 assembly MASM to compute first 41 fibonacci numbers. I initially had an array set to size 41, with 0's. This causes correct output for first 10ish values, with remaining indices being garbage values or blank. If I declare the array as size 100, it gives 20ish correct numbers... If i declare the array to size 300 elements, all 41 numbers are correct. Why is this? I want to declare the array as 41 and get 41 correct results.

INCLUDE Irvine32.inc

.data

display BYTE "Fibonacci number ", 0
equal BYTE " = ", 0

array DWORD 500 DUP(0)
fib DWORD OFFSET array

.code
main PROC
    mov fib, OFFSET array
    
    mov [fib], 0
    mov [fib + 4], 1
    mov [fib + 8], 1

    mov ecx, 3
    mov esi, 0
    
L1:

    mov edx, OFFSET display
    call WriteString
    
    mov eax, esi
    call WriteDec
    
    mov edx, OFFSET equal
    call WriteString
    
    mov eax, [fib + esi * 4]
    call WriteDec
    
    call Crlf
    inc esi
    
loop L1

    mov ecx, 38 
    mov esi, 3  
    
Fibo:
    mov edx, OFFSET display
    call WriteString
    
    mov eax, esi
    call WriteDec
    
    mov edx, OFFSET equal
    call WriteString
    
    mov eax, [fib + esi * 4 - 4]
    add eax, [fib + esi * 4 - 8]
    mov [fib + esi * 4], eax
    
    mov eax, [fib + esi * 4]
    call WriteDec
    
    inc esi
    call Crlf
    
loop Fibo

exit
main ENDP
end main
5
  • 1
    You're off by a level of indirection. fib contains the address of array, but mov [fib], 0 stores in fib itself, not in array; and mov [fib+4], 0 stores in whatever memory follows fib. x86 doesn't have a double-indirect addressing mode, in which the memory address to be accessed is itself fetched from some other address in memory. I think every instance of fib simply needs to be changed to array. The address of array is known at link time and can be used as an immediate; there's no point in storing it in memory and then loading it back later. Commented Oct 24, 2024 at 2:30
  • Every instance of fib, that is, except in mov fib, OFFSET array which you should simply delete. Commented Oct 24, 2024 at 2:30
  • @NateEldredge So if I need to work with pointers to manipulate the array, is the best way to just move the initial pointer into a register and then manipulate the register in order to change the original array? Commented Oct 24, 2024 at 2:36
  • mov [fib], 0 overwrites the pointer with 0. mov [fib + 4], 1 stores to memory you haven't allocated, past the end of that pointer. I don't know what you might be stepping on in the .data section of Irvine32 code you link with, but it might depend on alignment relative to a 16-byte boundary. Anyway, if you just want your code to work and be simpler, use fib DWORD 41 dup(0) instead of the 2 lines you have now. (edit: wrote this comment before Nate's, but the site was temporarily read-only. Basically redundant now) Commented Oct 24, 2024 at 3:07
  • @newGuy77: Yes, having a pointer in static storage in .data is not useful for working with an array. You only want pointers (or array indices) in registers, like mov esi, OFFSET fib (where fib is the label attached to 41 dup(0)). Commented Oct 24, 2024 at 3:10

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.