//----------------------------------------------------------------- // hyperfib.s (One answer to Final Exam's Question V) // // This is an assembly language implemention of the recursive // 'hyperfib()' function used in our 'hyperfib.cpp' program. // // compile using: g++ hyperfib.cpp hyperfib.s -o hyperfib // // programmer: ALLAN CRUSE // written on: 14 MAY 2008 //----------------------------------------------------------------- # offsets from EBP .equ n, 8 .equ f_1, -4 .equ f_2, -8 .equ f_3, -12 .section .text # # function prototype: int hyperfib( unsigned int n ); # hyperfib: push %ebp # preserve caller's EBP mov %esp, %ebp # setup local stackframe sub $12, %esp # allocate local storage cmpl $3, n(%ebp) # is n smaller than 3? jae recurs # no, then do recursion mov n(%ebp), %eax # else setup n in EAX jmp return # and exit to the caller recurs: # assignment: f_1 = hyperfib( n-1 ); mov n(%ebp), %eax # get caller's n-value sub $1, %eax # reduce n-value by 1 push %eax # push function argument call hyperfib # compute hyperfib( n-1 ) add $4, %esp # discard the augument mov %eax, f_1(%ebp) # save functuon's value # assignment: f_2 = hyperfib( n-2 ); mov n(%ebp), %eax # get caller's n-value sub $2, %eax # reduce n-value by 2 push %eax # push function-argument call hyperfib # compute hyperfib( n-2 ) add $4, %esp # discard the argument mov %eax, f_2(%ebp) # save function's value # assignment: f_3 = hyperfib( n-3 ); mov n(%ebp), %eax # get caller's n-value sub $3, %eax # reduce n-value by 3 push %eax # push function-argument call hyperfib # compute hyperfib( n-3 ) add $4, %esp # discard the argument mov %eax, f_3(%ebp) # save function's value # now return the sum: f_1 + f_2 + f_3 xor %eax, %eax # clear register EAX add f_1(%ebp), %eax # add our summand #1 add f_2(%ebp), %eax # add our summand #2 add f_3(%ebp), %eax # add our summand #3 return: mov %ebp, %esp # discard local storage pop %ebp # restore caller's EBP ret # give control to caller .global hyperfib # make entry-point visible .end # nothing more to assemble