.global main .section .data result: .asciz "fib(%llu) = %llu\n" a: .quad 0 .section .text main: push %rbp # Save the old base pointer to the # stack. # This also makes sure that rsp is # 16-byte aligned. movq %rsp, %rbp # Write the new base pointer. subq $16, %rsp # The stack frame is extended to fit # the three local variables and the # old value of the base pointer. # ABI requires 16-byte alignment! # This is not a problem here but it # is very noteworthy! movq 8(%rsi), %rdi # Retrieve the first argument from # the array of arguments. # The retrieved value is n in fib(n) call atoll # Convert the argument to long long movq %rax, %rdi # Save the long long as the argument # for the fib(n) function. movq %rax, a # Save the long long in a to use it # later in the printed output. call fib # Call the Fibonacci-function movq a, %rsi # Move the number a to rsi to use it # as the second argument for print. movq %rax, %rdx # Move to result of the fib(n)-call # to rdx, to use it as the third # argument for printf. movq $result, %rdi # Move the string to rdi, for use as # as the first argument for print. xor %al,%al # Specify that no vector arguments # are to be used. call printf # Print the string with values xor %rax, %rax # Make sure to return 0 to indicate # a successful run of the program. jmp end # Jump to end to return from the # program with the return value 0. fib: push %rbp # Save old rbp to stack and align # the stack pointer to 16-bytes, # since the return address already # has been pushed. Thus, the size # of the two values totals to # a size of 16-bytes. movq %rsp, %rbp # Write new base pointer. cmpq $1, %rdi # Compare the argument to 1. je one # If equal to one, return 1. cmpq $0, %rdi # Compare the argument to 0. jle zero # If equal to zero or negative go # to 'zero' and return zero. decq %rdi # Decrement n by 1. push %rdi # Save the value n - 1 in stack to # be able to recover it later. call fib # Call the function. The value of # rax is now equal to the return # value of fib(n-1). pop %rdi # Restore rdi = n-1 decq %rdi # Decrement rdi by 1. push %rax # Save the result of fib(n-1) call fib # Call the function. The value of # rax is now equal to the return # value of fib(n-2). addq (%rsp),%rax # Add fib(n-1) to rax which contains # the reuslt of fib(n-2). fib(n-1) # is retrieved from the stack. jmp end # Jump to 'end' to leave and return # from this call. zero: movq $0, %rax # Set return value to 0. jmp end one: movq $1, %rax # Set return value to 1. end: leave # Return the state of the base and # stack pointers to their # original state. By moving the # base pointers value into the # stack pointer and moving the old # base pointer value into the stack # pointer. ret # Return from the current function # with the contents of rax as the # return value.