I'm trying to teach myself assembly via MASM, below is my first implementation of the recursive form of the fibonacci sequence. I timed it against an equivalent C implementation in release mode and the C implementation was much better optimized. What can I do better? I haven't gotten the hang of how the various side effects of instructions impact the state of registers or flags yet, or, well, most things in assembly.
Assembly:
;extern "C" unsigned long fibonacci_asm_canonical(unsigned long number)
fibonacci_asm_canonical proc number: dword
LOCAL fib_lhs:DWORD
mov eax, number ; store number parameter in eax register (also used as return value).
.IF eax > 1
; recursively call this function, retrieving the value for the left-hand side.
dec eax
mov edx, eax
invoke fibonacci_asm_canonical, edx
mov fib_lhs, eax ; store the result of fibonacci_asm_canonical(number - 1) into fib_lhs.
mov eax, number ; store number parameter in eax register to set up right-hand side of addition.
; recursively call this function, retrieving the value for the right-hand side.
sub eax, 2
invoke fibonacci_asm_canonical, eax
;eax now contains result of fibonacci_asm_canonical(number - 2), following the invocation,
;so add it with the result of fibonacci_asm_canonical(number - 1) which is in fib_lhs.
add eax, fib_lhs
.ENDIF
ret
fibonacci_asm_canonical endp
C version:
unsigned long fib_canonical(unsigned long number)
{
if (number <= 1)
return number;
return fib_canonical(number - 1) + fib_canonical(number - 2);
}
```