Using x86 style jump table in C

2.2k views Asked by At

I am trying to do a jump table in C like this

    cmp     eax, dword 3                        ;max number
    ja      invalid                     ;default
    jmp     [eax*4+jumptable]           ;jump to handler
invalid:
    retn
jumptable:
    dd handle0, handle1, handle2, handle3
handle0:
    ....

and so forth

I started with this

void dohandler(int a, int b, void (*jumptable[4]) (int x))
    if (a > 3) return
    else jumptable[3 * 4](b);
}
int main() {
    void (*jumptable[4]) (int x);
    jumptable[0] = &handler1;
    ... etc

    dohandler(1,2,jumptable);
}
void handler1(int x) { ... }
.. etc

but its not working well..

3

There are 3 answers

0
Fred Larson On BEST ANSWER

Not sure, but I think you have a couple of problems here:

void dohandler(int a, int b, void (*jumptable[4]) (int x))
    if (a > 3) return
    else jumptable[3 * 4](b);
}

First, you don't use a in referencing your jump table, and I think that corresponds to the eax register in the assembly version. Second, don't multiply that by 4. I think that's intended to be the size of a pointer, and the array reference does that for you. So you end up with this:

void dohandler(int a, int b, void (*jumptable[4]) (int x))
    if (a > 3) return
    else jumptable[a](b);
}
0
Jeff Mercado On

jumptable is an array of pointers. Don't try to scale the offset, just index which pointer you want to reference.

void dohandler(int a, int b, void (*jumptable[4]) (int x))
    if (a >= 0 && a < 4)
        jumptable[a](b);
}
3
R.. GitHub STOP HELPING ICE On

switch will get compiled to a jumptable just like you want as long as the label values aren't too sparse. It may help to have a small size type (like unsigned char) for the expression, or to mask off the high bits, so the compiler doesn't add an extra "if-in-range" conditional before the jumptable jump, but that might not be so important.

Most importantly, experiment. Use gcc -S to examine the assembly output.