// this program show how to use an arbitrary address
// to perform a jump in inline assembler.
//
// Compile it with gcc:
// gcc change_eip.C
// Then run it:
// ./a.out
// You should obtain the following output
// 1426

#include <stdio.h>
#include <stdlib.h>

void dumbFct(void) __attribute__ ((__cdecl__));

void dumbFct()
{
        asm __volatile__(
                        "geteip:"
                        "movl (%esp), %eax;"
                        "ret;"
                        );
}

#define GetEip(v) asm __volatile__("call geteip;movl %%eax,%0;":"=g"(v));
#define GotoEip(r) asm __volatile__("pushl %0; ret;"::"g"(r));
#define Label(l) asm __volatile__(#l ":");
#define Jump(l) asm __volatile__("jmp " #l ";");
#define MuchNop asm __volatile__("nop;nop;nop;nop;nop;nop;nop;nop;");
#define Print(i) printf(#i);

int main(int argc, char** argv)
{
        long p;
        Print(1);
        GetEip(p);
        Jump(suite);
        MuchNop;
        Print(2);
        Jump(fin)
        Print(3);
        Label(suite);
        Print(4);
        GotoEip(p+8);
        Print(5);
        Label(fin);
        Print(6);
        Print(\n);
        return 0;
}
