1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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
|