################################################################## # Calculate the factorial of a number, using recursive functions # ################################################################## # # %rbx holds the number to factor # .section .data .section .text .globl _start _start: pushq $5 call factorial2 addq $8, %rsp # Turn back the stack pointer # Not really needed here, but good practice movq %rax, %rbx movq $1, %rax int $0x80 .type factorial, @function # This function is garbage, can be much more clean than this shit. factorial: pushq %rbp # Regular initial function stuff movq %rsp, %rbp # Save %rbp and reset it to %rsp movq 16(%rbp), %rbx # Get the argument passed into %rbx movq %rbx, %rcx # Copy it to %rcx and decrement it decq %rcx # here. %rcx will be the next element in the # factorial. # cmpq $1, %rcx # Compare it to 1 and exit if true, we are at je exit_factorial # the end of the factorial pushq %rbx # If not one, save the original argument in the pushq %rcx # stack and push the next value as argument to call factorial # the recursive call popq %rcx # pop value to restore stack pointer popq %rbx # restore %rbx and multiply it imul %rax, %rbx # by the result exit_factorial: movq %rbx, %rax # Move the result to %rax movq %rbp, %rsp # And do standard clean up before popq %rbp # returning. ret # This is a clean version after extra thought on this .type factorial2, @function factorial2: pushq %rbp # Basic function setup, save %rbp and movq %rsp, %rbp # setup it to current %rsp movq 16(%rbp), %rax # Get the argument passed into cmpq $1, %rax # je factorial2_end # We are at the last element in the factorial # Just return it decq %rax pushq %rax call factorial2 movq 16(%rbp), %rbx imulq %rbx, %rax factorial2_end: movq %rbp, %rsp popq %rbp ret