#ifndef cpu_h #define cpu_h #include struct cpu { enum {INIT = 0}; std::uint64_t rip, rsp, rbp, rbx, r12, r13, r14, r15; cpu() = default; std::uint64_t __attribute__((naked,noinline,returns_twice)) get() { asm volatile("mov (%%rsp),%0 \n" "lea 8(%%rsp),%1 \n" "mov %%rbp,%2 \n" "mov %%rbx,%3 \n" "mov %%r12,%4 \n" "mov %%r13,%5 \n" "mov %%r14,%6 \n" "mov %%r15,%7 \n" :"=r"(rip), "=r"(rsp), "=m"(rbp), "=m"(rbx), "=m"(r12), "=m"(r13), "=m"(r14), "=m"(r15)); asm volatile("ret"::"a"(INIT)); // optional: first call returns INIT = 0 } void __attribute__((naked,noinline,noreturn)) set(std::uint64_t ret = INIT + 1) const { asm volatile("mov %1,%%rsp \n" "push %0 \n" "mov %2,%%rbp \n" "mov %3,%%rbx \n" "mov %4,%%r12 \n" "mov %5,%%r13 \n" "mov %6,%%r14 \n" "mov %7,%%r15 \n" "mov %%rsi,%%rax \n" // optional: return value on get after set "ret \n" : :"m"(rip), "m"(rsp), "m"(rbp), "m"(rbx), "m"(r12), "m"(r13), "m"(r14), "m"(r15) :"memory"); } }; #endif // cpu_h