开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜