在 C 中使用 x86 风格的跳转表

发布于 2024-10-17 02:15:18 字数 674 浏览 2 评论 0原文

我正在尝试在 C 中做一个跳转表,就像这样

    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:
    ....

我从这个开始,

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

但它工作得不好..

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..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橙幽之幻 2024-10-24 02:15:18

jumptable 是一个指针数组。不要尝试缩放偏移量,只需索引要引用的指针即可。

void dohandler(int a, int b, void (*jumptable[4]) (int x))
    if (a >= 0 && a < 4)
        jumptable[a](b);
}

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);
}
陪你搞怪i 2024-10-24 02:15:18

不确定,但我认为您这里有几个问题:

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

首先,您没有使用 a 来引用跳转表,我认为这对应于 eax在汇编版本中注册。其次,不要将其乘以 4。我认为这应该是指针的大小,而数组引用可以为您做到这一点。所以你最终会得到这样的结果:

void dohandler(int a, int b, void (*jumptable[4]) (int x))
    if (a > 3) return
    else 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);
}
剩余の解释 2024-10-24 02:15:18

只要标签值不是太稀疏,switch 就会像您想要的那样编​​译为跳转表。为表达式使用小尺寸类型(例如 unsigned char)或屏蔽高位可能会有所帮助,因此编译器不会添加额外的“if-in-range”条件在跳转表跳转之前,但这可能并不那么重要。

最重要的是,实验。使用 gcc -S 检查汇编输出。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文