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