-
Notifications
You must be signed in to change notification settings - Fork 2
/
factorial.s
65 lines (55 loc) · 2.94 KB
/
factorial.s
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
# PURPOSE - Given a number, this program computes the
# factorial. For example, the factorial of
# 3 is 3 * 2 * 1, or 6. The factorial of
# 4 is 4 * 3 * 2 * 1, or 24, and so on.
#
# This program shows how to call a function recursively.
.section .data
# This program has no global data
.section .text
.globl _start
.globl factorial #this is unneeded unless we want to share
# this function among other programs
_start:
pushl $4 #The factorial takes one argument - the
# number we want a factorial of. So, it
# gets pushed
call factorial # run the factorial function
addl $4, %esp # Scrubs the parameter that was pushed on
# the stack
movl %eax, %ebx # factorial returns the answer in %eax, but
# we want it in %ebx to send it as our exit
# status
movl $1, %eax # call the kernel’s exit function
int $0x80
# This is the actual function definition
.type factorial,@function
factorial:
pushl %ebp # standard function stuff - we have to
# restore %ebp to its prior state before
# returning, so we have to push it
movl %esp, %ebp # This is because we don’t want to modify
# the stack pointer, so we use %ebp.
movl 8(%ebp), %eax # This moves the first argument to %eax
# 4(%ebp) holds the return address, and
# 8(%ebp) holds the first parameter
cmpl $1, %eax # If the number is 1, that is our base
# case, and we simply return (1 is
# already in %eax as the return value)
je end_factorial
decl %eax # otherwise, decrease the value
pushl %eax # push it for our call to factorial
call factorial # call factorial
movl 8(%ebp), %ebx # %eax has the return value, so we
# reload our parameter into %ebx
imull %ebx, %eax # multiply that by the result of the
# last call to factorial (in %eax)
# the answer is stored in %eax, which
# is good since that’s where return
# values go.
end_factorial:
movl %ebp, %esp # standard function return stuff - we
popl %ebp # have to restore %ebp and %esp to where
# they were before the function started
ret # return to the function (this pops the
# return value, too)