Skip to content
Snippets Groups Projects
Commit 3dc456e3 authored by j2-tulloch's avatar j2-tulloch :speech_balloon:
Browse files

Add new file

parent 4affc386
No related branches found
No related tags found
No related merge requests found
#
# 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment