提问人:JeffV 提问时间:9/7/2008 最后编辑:Pascal ThiventJeffV 更新时间:3/16/2015 访问量:55992
什么是跳台?
What is a jump table?
答:
在计算机编程中,一个分支 表(有时称为跳转 table)是用于描述 高效的转移方法 程序控制(分支)到另一个 程序的一部分(或不同的 可能是动态的程序 loaded) 使用分支表 指示。分支表 施工常用于以下情况 用汇编语言编程,但 也可以由编译器生成。
分支表由一个序列表组成 无条件分支列表 分支到 使用乘法创建的偏移量 指令的顺序索引 长度(内存中的字节数 被每个分支指令占用)。 它利用了机器的事实 分支的代码说明有一个 固定长度,可执行 大多数都非常有效 硬件,在以下情况下最有用 处理可能的原始数据值 可轻松转换为顺序式 索引值。鉴于这些数据,一个 分支表可以非常 有效;它通常由 以下步骤:(可选)验证 输入数据以确保它是 可以接受;将数据转换为 分支表的偏移量,这是 通常涉及乘以或 移动它以考虑 指令长度;并分支到 由 表和生成的偏移量:this 通常涉及添加 偏移到程序计数器上 注册。
此处描述了一个跳转表,但简而言之,它是 CPU 应根据特定条件跳转到的地址数组。例如,C switch 语句通常实现为跳转表,其中每个跳转条目将转到特定的“case”标签。
在嵌入式系统中,内存使用率非常高,许多构造最好使用跳转表而不是占用更多内存密集型的方法(如大规模的 if-else-if)。
维基百科总结得很好:
在计算机编程中,一个分支 表(有时称为跳转 table)是用于描述 高效的转移方法 程序控制(分支)到另一个 程序的一部分(或不同的 可能是动态的程序 loaded) 使用分支表 指示。分支表 施工常用于以下情况 用汇编语言编程,但 也可以由编译器生成。
...使用分支表和其他原始数据 数据编码在早期很常见 内存 价格昂贵,CPU 速度较慢且 紧凑的数据表示和 有效的替代方案选择是 重要。如今,它们很常见 用于嵌入式编程和 操作系统开发。
换句话说,当您的系统内存和/或 CPU 极度受限时,这是一个有用的结构,就像在嵌入式平台中经常出现的情况一样。
跳转表,通常称为分支表,通常仅由计算机使用。
编译器在汇编程序中创建所有标签的列表,并将所有标签链接到内存位置。跳转表几乎是内存中存储函数或变量或标签的参考卡。
因此,当一个函数执行时,它会跳回它以前的内存位置或跳到下一个函数,等等。
如果你在谈论我认为你是什么,你不仅在嵌入式系统中需要它们,而且在任何类型的编译/解释环境中都需要它们。
布莱恩·吉安福卡罗
跳转表可以是指向函数的指针数组,也可以是机器代码跳转指令的数组。如果您有一组相对静态的函数(例如系统调用或类的虚拟函数),则可以创建此表一次,并使用数组中的简单索引调用这些函数。这意味着检索指针并调用函数或跳转到机器代码,具体取决于所使用的表类型。
在嵌入式编程中这样做的好处是:
- 索引比机器代码或指针更节省内存,因此在受限环境中有可能节省内存。
- 对于任何特定函数,索引将保持稳定,更改函数只需换出函数指针即可。
如果确实会降低访问表的性能,但这并不比任何其他虚拟函数调用差。
跳转表,也称为分支表,是一系列指令,所有指令都无条件地分支到代码中的另一个点。
您可以将它们视为一个 switch(或 select)语句,其中填充了所有情况:
MyJump(int c)
{
switch(state)
{
case 0:
goto func0label;
case 1:
goto func1label;
case 2:
goto func2label;
}
}
请注意,没有返回 - 它跳转到的代码将执行返回,并且它将跳回到调用 myjump 的位置。
这对于基于状态变量执行某些代码的状态机非常有用。还有很多很多其他用途,但这是主要用途之一。
它用于您不想浪费时间摆弄堆栈并希望节省代码空间的地方。它特别适用于速度极其重要的中断处理程序,并且导致中断的外设只能由单个变量知道。这类似于带有中断控制器的处理器中的向量表。
一种用途是采用0.60美元的微控制器,为视频应用生成复合(TV)信号。Micro 并不强大 - 事实上,它只是勉强够快地写入每条扫描线。跳转表将用于绘制字符,因为从内存中加载位图需要很长时间,并使用 for() 循环将位图推出。取而代之的是,有一个单独的跳转到字母和扫描行,然后是 8 条左右的指令,这些指令实际上将数据直接写入端口。
-亚当
评论
跳转表通常(但不限于)用于有限状态机,以使其成为数据驱动。
代替嵌套的开关/外壳
switch (state)
case A:
switch (event):
case e1: ....
case e2: ....
case B:
switch (event):
case e3: ....
case e1: ....
您可以创建一个 2D 数组或函数指针,然后调用handleEvent[state][event]
评论