From 2e928cfc522019fd93c91060b691c1f77991fbd3 Mon Sep 17 00:00:00 2001
From: j2-tulloch <james2.tulloch@live.uwe.ac.uk>
Date: Fri, 5 Jan 2024 14:48:16 +0000
Subject: [PATCH] Upload New File

---
 Assignment/Task 3/context.s | 106 ++++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)
 create mode 100644 Assignment/Task 3/context.s

diff --git a/Assignment/Task 3/context.s b/Assignment/Task 3/context.s
new file mode 100644
index 0000000..a7bc408
--- /dev/null
+++ b/Assignment/Task 3/context.s	
@@ -0,0 +1,106 @@
+#
+# Author: Benedict R. Gaster
+# Module: Advanced Systems Programming
+#
+# C API (defined in context.hpp)
+# 
+# struct Context {
+#   void *rip, *rsp;
+#   void *rbx, *rbp, *r12, *r13, *r14, *r15;
+# };
+# extern "C" void get_context(Context *c);
+# extern "C" void set_context(Context *c);
+# extern "C" void swap_context(Context *out, Context *in);
+#
+# We are dependent here on the Sys V x86-64 ABI:
+#   https://gitlab.com/x86-psABIs/x86-64-ABI/-/jobs/artifacts/master/raw/x86-64-ABI/abi.pdf?job=build
+#
+# Derived from the excellent blog post: https://graphitemaster.github.io/fibers/
+#
+
+# extern "C" void get_context(Context *c);
+.type get_context, @function
+.global get_context
+get_context:
+  # Save the return address and stack pointer.
+  movq (%rsp), %r8
+  movq %r8, 8*0(%rdi)
+  leaq 8(%rsp), %r8
+  movq %r8, 8*1(%rdi)
+
+  # Save preserved registers.
+  movq %rbx, 8*2(%rdi)
+  movq %rbp, 8*3(%rdi)
+  movq %r12, 8*4(%rdi)
+  movq %r13, 8*5(%rdi)
+  movq %r14, 8*6(%rdi)
+  movq %r15, 8*7(%rdi)
+
+  # Return.
+  xorl %eax, %eax
+  ret
+
+# extern "C" void set_context(Context *c);  
+.type set_context, @function
+.global set_context
+set_context:
+  # Should return to the address set with {get, swap}_context.
+  movq 8*0(%rdi), %r8
+
+  # Load new stack pointer.
+  movq 8*1(%rdi), %rsp
+
+  # Load preserved registers.
+  movq 8*2(%rdi), %rbx
+  movq 8*3(%rdi), %rbp
+  movq 8*4(%rdi), %r12
+  movq 8*5(%rdi), %r13
+  movq 8*6(%rdi), %r14
+  movq 8*7(%rdi), %r15
+
+  # Push RIP to stack for RET.
+  pushq %r8
+
+  # Return.
+  xorl %eax, %eax
+  ret
+
+# extern "C" void swap_context(Context *out, Context *in);
+.type swap_context, @function
+.global swap_context
+swap_context:
+  # Save the return address.
+  movq (%rsp), %r8
+  movq %r8, 8*0(%rdi)
+  leaq 8(%rsp), %r8
+  movq %r8, 8*1(%rdi)
+
+  # Save preserved registers.
+  movq %rbx, 8*2(%rdi)
+  movq %rbp, 8*3(%rdi)
+  movq %r12, 8*4(%rdi)
+  movq %r13, 8*5(%rdi)
+  movq %r14, 8*6(%rdi)
+  movq %r15, 8*7(%rdi)
+
+  # Should return to the address set with {get, swap}_context.
+  movq 8*0(%rsi), %r8
+
+  # Load new stack pointer.
+  movq 8*1(%rsi), %rsp
+
+  # Load preserved registers.
+  movq 8*2(%rsi), %rbx
+  movq 8*3(%rsi), %rbp
+  movq 8*4(%rsi), %r12
+  movq 8*5(%rsi), %r13
+  movq 8*6(%rsi), %r14
+  movq 8*7(%rsi), %r15
+
+  # Push RIP to stack for RET.
+  pushq %r8
+
+  # Return.
+  xorl %eax, %eax
+  ret
+
-- 
GitLab