summaryrefslogtreecommitdiff
path: root/PGU/OLD/chapter4
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-10 22:55:07 +0200
committerCarlos Maiolino <[email protected]>2025-07-10 22:56:55 +0200
commitd98f46ce647846b0aa30b2e16a30fd4e152a1bf5 (patch)
tree267474fcc77cf20b428f6f4c7f768ca09f4cfe0e /PGU/OLD/chapter4
parent869e68986aa8f69af6e7842260a68d1e5c6f796f (diff)
Add new code
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'PGU/OLD/chapter4')
-rw-r--r--PGU/OLD/chapter4/call_power.c12
-rw-r--r--PGU/OLD/chapter4/factorial.s73
-rw-r--r--PGU/OLD/chapter4/libpower.s48
-rw-r--r--PGU/OLD/chapter4/power.s90
4 files changed, 223 insertions, 0 deletions
diff --git a/PGU/OLD/chapter4/call_power.c b/PGU/OLD/chapter4/call_power.c
new file mode 100644
index 0000000..b6bb7e0
--- /dev/null
+++ b/PGU/OLD/chapter4/call_power.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+int power(int a, int b);
+
+int main(void) {
+ int a = 2;
+ int b = 6;
+
+ printf("Power == %d\n", power(2, 6));
+
+ return 0;
+}
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
+
diff --git a/PGU/OLD/chapter4/libpower.s b/PGU/OLD/chapter4/libpower.s
new file mode 100644
index 0000000..5172cda
--- /dev/null
+++ b/PGU/OLD/chapter4/libpower.s
@@ -0,0 +1,48 @@
+# Simple example of functions in ASM, following System V ABI
+# and C calling convention
+
+# Everything is stored in registers, so, we have nothing in data section
+
+####################
+# #
+# Function power() #
+# #
+####################
+
+# Remember the return address (where the program should keep executing after
+# function return), is also pushed into the stack by the 'call' command.
+
+# Remember, in x86_64 architecture, the Stack grows 'downwards', so, every time
+# we want to look back in the stack, we need to add to the current stack
+# pointer, other than subtract.
+
+# Ex:
+# 56 <- stack 'bottom'
+# 48 pushq
+# 40 pushq
+# 32 <- %rsp (top of the stack)
+
+.type power, @function
+power:
+ pushq %rbp
+ movq %rsp, %rbp
+ movq 16(%rbp), %rcx # Holds the Base number. 16 because:
+ # Current %rsp (pushq %rbp) plus the
+ # implicit return address pushed by
+ # the call command
+
+ movq 24(%rbp), %rbx # Holds the power (pushed first before
+ # function call
+ movq %rcx, %rax
+
+loop:
+ cmpq $1, %rbx
+ je return
+ imul %rcx, %rax
+ decq %rbx
+ jmp loop
+
+return:
+ movq %rbp, %rsp
+ popq %rbp
+ ret
diff --git a/PGU/OLD/chapter4/power.s b/PGU/OLD/chapter4/power.s
new file mode 100644
index 0000000..fe89eae
--- /dev/null
+++ b/PGU/OLD/chapter4/power.s
@@ -0,0 +1,90 @@
+# Simple example of functions in ASM, following System V ABI
+# and C calling convention
+
+# Everything is stored in registers, so, we have nothing in data section
+.section .data
+
+.section .text
+
+.globl _start
+
+_start:
+ pushq $3 # Second argument
+ pushq $2 # First argument
+ call power # call function power()
+
+ addq $16, %rsp # Remove arguments from the stack
+ # Could have popped'em, but we don't
+ # need them anymore, so, just move
+ # the stack pointer back
+
+ pushq %rax # Save return value of power()
+
+# Call power () again
+ pushq $2 # Push second argument
+ pushq $5 # Push first argument
+ call power
+
+ addq $16, %rsp # Move stack pointer back
+
+ popq %rbx # Second answer is already in %eax
+ # (returned from power), first answer
+ # was pushed into the stack before, so,
+ # just pop it into %ebx.
+
+ addq %rax, %rbx # Sum up both results (and %ebx is already the
+ # exit()'s return value
+
+# Call exit()
+
+ movq $1, %rax
+ int $0x80
+
+
+
+
+####################
+# #
+# Function power() #
+# #
+####################
+
+# Remember the return address (where the program should keep executing after
+# function return), is also pushed into the stack by the 'call' command.
+
+# Remember, in x86_64 architecture, the Stack grows 'downwards', so, every time
+# we want to look back in the stack, we need to add to the current stack
+# pointer, other than subtract.
+
+# Ex:
+# 56 <- stack 'bottom'
+# 48 pushq
+# 40 pushq
+# 32 <- %rsp (top of the stack)
+
+#Tread symbol 'power' as a function
+.type power,@function
+
+power:
+ pushq %rbp
+ movq %rsp, %rbp
+ movq 16(%rbp), %rcx # Holds the Base number. 16 because:
+ # Current %rsp (pushq %rbp) plus the
+ # implicit return address pushed by
+ # the call command
+
+ movq 24(%rbp), %rbx # Holds the power (pushed first before
+ # function call
+ movq %rcx, %rax
+
+loop:
+ cmpq $1, %rbx
+ je return
+ imul %rcx, %rax # The result is already stored in %rax
+ decq %rbx
+ jmp loop
+
+return:
+ movq %rbp, %rsp
+ popq %rbp
+ ret