2

私はこのように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

しかし、うまく機能していません..

4

3 に答える 3

4

jumptableポインタの配列です。オフセットをスケーリングしようとしないでください。参照したいポインターにインデックスを付けるだけです。

void dohandler(int a, int b, void (*jumptable[4]) (int x))
    if (a >= 0 && a < 4)
        jumptable[a](b);
}
于 2011-02-11T06:13:13.210 に答える
3

よくわかりませんが、ここにはいくつかの問題があると思います。

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);
}
于 2011-02-11T06:14:34.473 に答える
3

switchラベル値がまばらでない限り、必要に応じてジャンプテーブルにコンパイルされます。式に小さいサイズの型 ( などunsigned char) を使用するか、上位ビットをマスクすると役立つ場合があります。そのため、コンパイラはジャンプテーブル ジャンプの前に追加の「範囲内の場合」条件を追加しませんが、そうではない場合があります。とても重要です。

最も重要なことは、実験することです。gcc -Sアセンブリ出力を調べるために使用します。

于 2011-02-11T06:15:23.333 に答える