You are on page 1of 5

fib(n)= 1,

fib(n)= fib(n-1)+fib(n-2),

CSCI 264 Assembly Language


Recursion: Fibonacci Numbers
n<2
n>=2

fragment of C++ code:

extern C int fib(int n);


.
int n, result;
cin >> n;
result = fib(n);
cout << result;
assembly code for function fib
global fib
push ecx
mov eax, [esp+8]
cmp eax, 2
jae els
mov eax, 1
jmp dun
els:
dec eax
mov ecx, eax
push eax
call fib
add esp, 4
dec ecx
push ecx
mov ecx, eax
call fib
add esp, 4
add eax, ecx
dun: pop ecx
ret
fib:

Address ( assume ESP=


100 at the initial point)

value

explanation

76: ESP after PUSH ECX


inside the fib for n = 1

01
00
00
00
80: ESP after CALL fib
EE
the address of return
EE
statement pushed into
EE
Stack
EE
84: ESP after PUSH EAX
01
inside the function fib
00
for n = 2
00
00
88: ESP after PUSH ECX
**
in function fib
**
**
**
92: ESP after the address of FF
the return statement
FF
FF
FF
96: ESP after inserting
02
parameter in C++ main
00
00
00
100: ESP initial value
MOV EAX, [ESP+2]
CMP EAX, 2 JAE ELS
ELS: DEC EAX
MOV ECX, EAX
PUSH EAX CALL fib

The address of ADD ESP, 4 in function


fib for n = 2 was pushed inside
EAX was decremented by 1 and pushed
inside the stack, this will be the parameter
for the recursive call fib(n-1) ( fib (1))
function fib: garbage that was in ECX
was pushed inside the stack
address of cout << result from main ( C++)

n =2 , function call from main (C++) with


parameter n =2

; EAX gets 2
; EAX =2 there is a jump to els
; EAX gets 1
; ECX gets 1
; the function will return to the beginning of fib
;with parameter 1

..; now we are inside function fib again with parameter 1


PUSH ECX
; ECX equals 1
MOV EAX, [ESP+8]
; EAX gets 1
CMP EAX, 2
JAE ELS
; no jump this time
MOV EAX, 1
; EAX gets 1 this is the return value for fib(1)
JMP DUN

DUN: POP ECX


RET

; ECX gets 1
; return to the caller function
; the execution came back to fib with n = 2 to the line ADD ESP, 4

; after we came back from the n =1 to n=2


ADD ESP, 4
DEC ECX
; ECX gets 0 ( n-2)
PUSH ECX
;the value at the top of the stack is 00 00 00 00
MOV ECX, EAX
; ECX gets 1
;( ECX will keep the value of
;fib ( n-1): fib(1) in our case)
CALL fib
; returned address pushed
..; now we are inside function fib again with parameter 0
PUSH ECX ; ECX is 1, the top value is 01 00 00 00
MOV EAX, [ESP+8]
; EAX gets 0
CMP EAX, 2
JAE ELS
; no jump
MOV EAX, 1
; EAX gets 1
JMP DUN
..
DUN: POP ECX
; ECX gets 1
RET
; return to fib with n = 2 to the line add esp, 4 after the second call to fib
ADD ESP, 4
ADD EAX, ECX

; ESP = ESP + 4
; EAX = EAX +ECX = 1
;(EAX is 1 the value of fib(2) = fib(0) + fib(1)
;ECX is 1 ECX kept the value of fib(1))

POP ECX
RET
After the execution will return to main in C++ the command ADD ESP, 4 will be
executed in the background

Example:

n!= 1 ,
n! = n*(n-1)! ,
fact:

els:

dun:

n =0
n >0

global fact
push ecx
move eax, [esp+8]
cmp eax, 0
ja els
move eax, 1
jmp dun
mov ecx, eax
dec eax
push eax
call fact
add esp, 4
mul ecx
pop ecx
ret

You might also like