Using x86 style jump table in C
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, 开发者_Go百科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..
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);
}
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);
}
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.
精彩评论