summaryrefslogtreecommitdiff
path: root/PGU/CHAP4/power.s
diff options
context:
space:
mode:
Diffstat (limited to 'PGU/CHAP4/power.s')
-rw-r--r--PGU/CHAP4/power.s94
1 files changed, 94 insertions, 0 deletions
diff --git a/PGU/CHAP4/power.s b/PGU/CHAP4/power.s
new file mode 100644
index 0000000..124586e
--- /dev/null
+++ b/PGU/CHAP4/power.s
@@ -0,0 +1,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
+
+
+
+