有人可以解释跳转表的机制吗?为什么嵌入式系统需要?
7 回答
跳转表可以是指向函数的指针数组或机器代码跳转指令数组。如果您有一组相对静态的函数(例如系统调用或类的虚函数),那么您可以创建此表一次并使用数组中的简单索引调用函数。这将意味着检索指针并调用函数或跳转到机器代码,具体取决于所使用的表的类型。
在嵌入式编程中这样做的好处是:
- 索引比机器代码或指针更节省内存,因此在受限环境中可以节省内存。
- 对于任何特定函数,索引将保持稳定,更改函数只需要换出函数指针。
If 确实花费了您一点点访问表的性能,但这并不比任何其他虚函数调用差。
跳转表,也称为分支表,是一系列指令,全部无条件地跳转到代码中的另一个点。
您可以将它们视为填充所有案例的 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 条左右的指令,它们实际上将数据直接写入端口。
-亚当
在计算机编程中,分支表(有时称为跳转表)是一个术语,用于描述将程序控制(分支)转移到程序的另一部分(或可能已动态加载的不同程序)的有效方法分支指令表。分支表结构通常在用汇编语言编程时使用,但也可以由编译器生成。
分支表由一系列无条件分支指令组成,这些指令使用通过将顺序索引乘以指令长度(每个分支指令占用的内存中的字节数)创建的偏移量进行分支。它利用了用于分支的机器代码指令具有固定长度并且可以由大多数硬件非常有效地执行这一事实,并且在处理可以轻松转换为顺序索引值的原始数据值时最有用。给定这样的数据,分支表可以非常有效;它通常包括以下步骤: 可选地验证输入数据以确保其可接受;将数据转换为分支表的偏移量,这通常涉及将其乘以或移位以考虑指令长度;并跳转到由表的基数和生成的偏移量组成的地址:这通常涉及将偏移量添加到程序计数器寄存器上。
跳转表通常(但不限于)在有限状态机中使用,以使其成为数据驱动的。
而不是嵌套的开关/案例
switch (state)
case A:
switch (event):
case e1: ....
case e2: ....
case B:
switch (event):
case e3: ....
case e1: ....
你可以制作一个二维数组或函数指针,然后调用handleEvent[state][event]
此处描述了一个跳转表,但简而言之,它是 CPU 应根据特定条件跳转到的地址数组。例如,C switch 语句通常实现为跳转表,其中每个跳转条目将转到特定的“case”标签。
在内存使用非常宝贵的嵌入式系统中,使用跳转表而不是更多内存密集型方法(如大量 if-else-if)可以更好地服务于许多结构。
维基百科总结得很好:
在计算机编程中,分支表(有时称为跳转表)是一个术语,用于描述将程序控制(分支)转移到程序的另一部分(或可能已动态加载的不同程序)的有效方法分支指令表。分支表结构通常在用汇编语言编程时使用,但也可以由编译器生成。
... 在计算的早期,当内存昂贵、CPU 速度较慢、紧凑的数据表示和有效选择替代方案很重要时,使用分支表和其他原始数据编码很常见。如今,它们通常用于嵌入式编程和操作系统开发。
换句话说,当您的系统内存和/或 CPU 非常有限时使用它是一个有用的结构,这在嵌入式平台中通常是这种情况。
跳转表,通常称为分支表,通常仅由机器使用。
编译器创建一个汇编程序中所有标签的列表,并将所有标签链接到一个内存位置。一个跳转表几乎是一个参考卡,一个函数或变量或任何标签可能存储在内存中。
因此,当一个函数执行时,在完成时它会跳回到它之前的内存位置或跳转到下一个函数,等等。
如果您谈论我认为您是什么,您不仅需要在嵌入式系统中使用它们,而且在任何类型的编译/解释环境中都需要它们。
布赖恩·吉安福卡罗