Skip to content
Snippets Groups Projects
Commit b0403e2f authored by a33-rogers's avatar a33-rogers
Browse files

help me

parent 64de2b87
Branches
No related tags found
No related merge requests found
# Context
This small library for saving and restoring a fiber's context. It is for use in the module Advanced Systems Programming Worksheet 1.
It requires an platform that supports System V ABI.
This API is derived from the excellent blog post: https://graphitemaster.github.io/fibers/. Well worth a read!
## API
The following API is defined:
```c++
struct Context {
void *rip, *rsp;
void *rbx, *rbp, *r12, *r13, *r14, *r15;
};
extern "C" int get_context(Context *c);
extern "C" void set_context(Context *c);
extern "C" void swap_context(Context *out, Context *in);
```
## Building
```bash
clang++ -c context.s
```
Then link in the resulting ```context.o``` to an application using the API.
/*
* Author: Benedict R. Gaster
* Module: Advanced Systems Programming
*
* Derived from the excellent blog post: https://graphitemaster.github.io/fibers/
*/
#pragma once
struct Context {
void *rip, *rsp;
void *rbx, *rbp, *r12, *r13, *r14, *r15;
};
extern "C" int get_context(Context *c);
extern "C" void set_context(Context *c);
extern "C" void swap_context(Context *out, Context *in);
\ No newline at end of file
#
# 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
......@@ -12,7 +12,7 @@ int main(){
func foo:
2 output "you called foo"
3 # cannot return to main as they have different stack
4 call function exit
4 call function exit`
5
6 func main:
7 # allocate space for stack
......
context @ 4d1a25c6
Subproject commit 4d1a25c67a7215d32a18719c8cdbe2ad70582458
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment