summaryrefslogtreecommitdiff
path: root/PGU/CHAP4/power.s
blob: 124586ec45d45f3b9343da4dd1ba369095f0d1c7 (plain)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Power Program
#
# Computes the value of a number raised to a power
# using functions.
#

# Everything in the main program is stored in registers
# no need for data section
.section .data

.section .text

.globl _start

_start:

	pushq $3	# Second argument (power)
	pushq $2	# First argument  (base)
	call power	# Call the function power

	# Cleanup stack removing the arguments from it
	addq $16, %rsp

	# Save the answer in the stack before calling power again
	push %rax

	pushq $2	# Second argument (Power)
	pushq $5	# First argument (Base)
	call power

	addq $16, %rsp	# Cleanup stack

	# Second answer is already in %rax, get the first
	# back from stack to %rdi
	popq %rdi

	# Just add them
	addq %rax, %rdi

	#Sum is already in %rdi, just call exit() with %rdi as argument
	movq $60, %rax
	syscall



##################
# Power Function #
##################

# - First Arg  - Base power
# - Second Arg - The power to raise it to
#
# NOTE: So far, power must be 1 or greater
#
# Variables
#
# - %rbx - holds the base number
# - %rcx - holds the power (also acts as a counter)
# - -8(%rbp) holds the current result

.type power, @function

power:
	pushq %rbp		# Save old Base Pointer
	movq  %rsp, %rbp	# make stack pointer the base pointer
	subq  $8, %rsp		# Add space in stack for local storage

	movq 16(%rbp), %r8	# Retrieve Base number from stack to %rbx
	movq 24(%rbp), %r9	# Retrieve second argument from stack to %rcx

	movq %r8, -8(%rbp)	# Store current result (the operand by itself)

power_loop_start:
	cmpq $1, %r9		# If power is 1, we are done
	je end_power

	movq -8(%rbp), %rax	# Move current into %rax
	imulq %r8, %rax		# Multiply current result by base number

	movq %rax, -8(%rbp)	# Save current result

	decq %r9		# Decrease the power (using as a counter)
	jmp power_loop_start

end_power:
	movq -8(%rbp), %rax	# Retrieve end result into %rax
				# Return value goes into %rax
	movq %rbp, %rsp		# Restore stack pointer
	popq %rbp		# Restore base pointer
	ret