diff options
Diffstat (limited to 'PGU/OLD/chapter4/factorial.s')
| -rw-r--r-- | PGU/OLD/chapter4/factorial.s | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/PGU/OLD/chapter4/factorial.s b/PGU/OLD/chapter4/factorial.s new file mode 100644 index 0000000..749f57e --- /dev/null +++ b/PGU/OLD/chapter4/factorial.s @@ -0,0 +1,73 @@ +################################################################## +# 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 + |
