Skip to content

Instantly share code, notes, and snippets.

@simonask
Created July 8, 2009 18:45
Show Gist options
  • Save simonask/143068 to your computer and use it in GitHub Desktop.
Save simonask/143068 to your computer and use it in GitHub Desktop.
/*
My very own setjmp.
*/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct Continuation {
void* rip;
void* rsp;
void* rbp;
} Continuation;
void resume(Continuation* cc)
{
__asm__(
// restore registers
"movq %0, %%rdi\n"
"movq %1, %%rsp\n"
"movq %2, %%rbp\n"
"movq %3, %%r8\n"
"movq $1, %%rax\n"
// resume!
"jmpq *%%r8\n"
:
: "r"(cc), "m"(cc->rsp), "m"(cc->rbp), "m"(cc->rip)
: "%rdi", "%rsi", "%rsp", "%rbp", "%r8"
);
}
bool save(Continuation* cc)
{
__asm__(
// rsp is rsp, since the stack size of this function is 0
"movq %%rsp, %0\n"
// rbp stored on the stack
"movq (%%rsp), %%rax\n"
"movq %%rax, %1\n"
// read instruction pointer for calling function from the stack
"movq %%rbp, %%r8\n"
"movq 8(%%r8), %%rax\n"
"movq %%rax, %2\n"
: "=m"(cc->rsp), "=m"(cc->rbp), "=m"(cc->rip)
:
: "%rax"
);
return false;
}
int main (int argc, char const *argv[])
{
Continuation cc;
printf("cc is at 0x%llx\n", &cc);
printf("before\n");
if (save(&cc)) {
printf("returned from continuation!\n");
printf("muuuh\n");
} else {
printf("returning directly\n");
resume(&cc);
printf("after resume -- should never be reached!\n");
}
printf("exiting\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment