有人可以解释一下跳转表的机制以及为什么嵌入式系统需要它吗?

有帮助吗?

解决方案

跳转表可以是函数指针数组,也可以是机器代码跳转指令数组。如果您有一组相对静态的函数(例如系统调用或类的虚拟函数),那么您可以创建此表一次并使用数组的简单索引来调用函数。这意味着检索指针并调用函数或跳转到机器代码,具体取决于所使用的表的类型。

在嵌入式编程中这样做的好处是:

  1. 索引比机器代码或指针的内存效率更高,因此在受限环境中具有节省内存的潜力。
  2. 对于任何特定函数,索引将保持稳定,更改函数只需要交换函数指针。

如果访问该表确实会花费一点点性能,但这并不比任何其他虚拟函数调用差。

其他提示

跳转表,也称为分支表,是一系列指令,全部无条件分支到代码中的另一个点。

您可以将它们视为一个 switch(或 select)语句,其中所有情况都被填充:

MyJump(int c)
{
   switch(state)
   {
      case 0:
         goto func0label;
      case 1:
         goto func1label;
      case 2:
         goto func2label;
   }
}

请注意,没有返回 - 它跳转到的代码将执行返回,并且它将跳回到调用 myjump 的地方。

这对于根据状态变量执行某些代码的状态机很有用。还有很多很多其他用途,但这是主要用途之一。

它用于您不想浪费时间摆弄堆栈并希望节省代码空间的情况。它特别适用于速度极其重要的中断处理程序,并且导致中断的外设仅由单个变量所知。这类似于带有中断控制器的处理器中的向量表。

一种用途是采用 0.60 美元的微控制器,为视频应用生成复合 (TV) 信号。微控制器的功能并不强大——事实上,它的速度不足以写入每条扫描线。跳转表将用于绘制字符,因为从内存加载位图需要很长时间,并使用 for() 循环将位图推出。相反,有一个单独的跳转到字母和扫描线,然后是 8 条左右的指令,这些指令实际上将数据直接写入端口。

-亚当

描述了一个跳转表 这里, ,但简单地说,它是 CPU 应根据某些条件跳转到的地址数组。例如,C switch 语句通常被实现为跳转表,其中每个跳转条目将转到特定的“case”标签。

在内存使用非常宝贵的嵌入式系统中,使用跳转表而不是更占用内存的方法(如大量的 if-else-if)可以更好地服务于许多结构。

维基百科 总结得很好:

在计算机编程中,分支表(有时称为跳台)是一个术语,用于描述一种有效的方法,用于将程序控制(分支)传输到程序的另一部分(或使用动态加载的其他程序)的另一部分(或分支说明表。分支表构造通常是在用汇编语言编程时使用的,但也可能由编译器生成。

...使用分支表和其他原始数据编码在计算早期内存昂贵时很常见,CPU较慢,紧凑的数据表示和有效的替代选择很重要。如今,它们通常用于嵌入式编程和操作系统开发中。

换句话说,当您的系统内存和/或 CPU 极其有限(嵌入式平台中经常出现这种情况)时,它是一个有用的结构。

来自维基百科:

在计算机编程中,分支表(有时称为跳台)是一个术语,用于描述一种有效的方法,用于将程序控制(分支)传输到程序的另一部分(或使用动态加载的其他程序)的另一部分(或分支说明表。分支表构造通常是在用汇编语言编程时使用的,但也可能由编译器生成。

一个分支表由无条件分支指令的串行列表组成,该列表使用通过将顺序索引乘以指令长度(每个分支指令占据的内存中的字节数)来创建的偏移量。它利用了这样一个事实,即用于分支的机器代码指令具有固定的长度,并且可以通过大多数硬件可以非常有效地执行,并且在处理可以轻松转换为顺序索引值的原始数据值时最有用。给定这样的数据,分支表可以非常有效。它通常包括以下步骤:可选地验证输入数据以确保其可接受;将数据转换为偏移到分支表中,这通常涉及将其倍增或移动以考虑指令长度;并分支到由表的底部和生成的偏移量组成的地址:这通常涉及在程序计数器注册中增加偏移量。

跳转表,通常称为分支表,通常仅由机器使用。

编译器在汇编程序中创建所有标签的列表,并将所有标签链接到内存位置。跳转表几乎是一个参考卡,函数或变量或任何标签可能存储在内存中。

因此,当一个函数执行时,完成后它会跳回之前的内存位置或跳转到下一个函数,等等。

如果你谈论的是我认为你是什么,你不仅需要它们在嵌入式系统中,而且在任何类型的编译/解释环境中。

布赖恩·吉安福卡罗

跳转表通常(但不限于)用于 有限状态机 让他们数据驱动。

而不是嵌套的 switch/case

  switch (state)
     case A:
       switch (event):
         case e1: ....
         case e2: ....
     case B:
       switch (event):
         case e3: ....
         case e1: ....

你可以创建一个二维数组或函数指针,然后调用 handleEvent[state][event]

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top