dComArk15/Aflevering5-x86-64/fib-pure-as.s

97 lines
4.4 KiB
ArmAsm
Raw Permalink Normal View History

2016-01-03 12:29:05 +00:00
.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.