0

我知道jump tables主要用于在程序集中创建 switch 语句:

int a = 5;
switch (a){
  case 5:
  ...
   break;
  ...
} 

在这种情况下,跳转只是一个指向必须工作的内存地址的instructions指针case 5

如果我没记错的话,alookup table在数组中有预先计算的结果吗?所以不是编写代码来计算它们,而是返回数组索引?有点像HashMap.

以上两个听起来跟我很像,是不是基本一样?一个指向指令,另一个返回预先计算的结果?

4

3 回答 3

0

如果我没记错的话,查找表在数组中有预先计算的结果吗?所以不是编写代码来计算它们,而是返回数组索引?有点像HashMap。

正确的。存储在该索引处的内容可能是数据、指向数据的指针或指向函数的指针等。

跳转表只是一个查找表,其中每个索引对应一个函数,最常见的是在 C 中实现为函数指针数组。

于 2020-06-22T14:45:17.500 回答
0

引擎盖下发生的事情是编译器。但你的观察是对的。这是一个片段,展示了编译器通常对 switch 语句所做的事情:

#include <stdio.h>

void foo(void) { printf("foo\n"); }
void bar(void) { printf("bar\n"); }

int main(void)
{
    // Array of size 2 of pointer to function without arguments returning void
    // Yes, declaring function pointers is not intuitive...
    void (*f[2])(void);

    f[0] = foo;
    f[1] = bar;

    int x;
    printf("Enter a number (0 or 1): ");
    scanf("%d", &x);

    printf("Using switch\n");
    switch(x) {
    case 0: foo(); break;
    case 1: bar(); break;
    }

    printf("Using array of function pointers\n");
    f[x]();
}
于 2020-06-22T15:06:44.427 回答
0

正如您所提到的,跳转表是本机代码,其排列方式很容易根据整数值跳转。如果跳转表仅由短跳转指令组成,您可以将您的开关值乘以 3 并添加表中第一个条目的偏移量并跳转(JMPCALL)到它。

另一方面,查找表只是原始数据。它仍然以打包格式存储,因此您可以通过对索引 ( size * index + offset) 的线性操作来访问它,但要使用它,您可以使用间接移动 ( MOV dest, [expression]) 而不是物理跳转到它。

请记住,查找表只是一种优化,尽管它很大,您也可以使用跳转表将值加载到寄存器中。这是一种关系。

于 2020-06-22T14:46:31.477 回答