Использование таблицы переходов в стиле x86 в C - PullRequest
2 голосов
/ 11 февраля 2011

Я пытаюсь сделать таблицу переходов в 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

но это не работает хорошо ..

Ответы [ 3 ]

4 голосов
/ 11 февраля 2011

jumptable - это массив указателей.Не пытайтесь масштабировать смещение, просто укажите, на какой указатель вы хотите сослаться.

void dohandler(int a, int b, void (*jumptable[4]) (int x))
    if (a >= 0 && a < 4)
        jumptable[a](b);
}
3 голосов
/ 11 февраля 2011

switch будет скомпилирован в таблицу переходов, как вы хотите, если значения меток не слишком редки. Это может помочь иметь тип маленького размера (например, unsigned char) для выражения или маскировать старшие биты, чтобы компилятор не добавлял дополнительное условие «if-in-range» перед прыжковым прыжком, но это может быть не так важно.

Самое главное, эксперимент. Используйте gcc -S для проверки вывода сборки.

3 голосов
/ 11 февраля 2011

Не уверен, но я думаю, что у вас есть пара проблем:

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

Во-первых, вы не используете a в ссылках на таблицу переходов, и я думаю, что это соответствует1005 * зарегистрируйтесь в сборочной версии.Во-вторых, не умножайте это на 4. Я думаю, что это размер указателя, и ссылка на массив сделает это за вас.Таким образом, вы в конечном итоге с этим:

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