有人可以解释跳转表的机制吗,为什么嵌入式系统需要跳转表?
跳转表可以是指向函数的指针数组,也可以是机器码跳转指令的数组。如果您具有一组相对静态的函数(例如,系统调用或某个类的虚函数),则可以一次创建该表,然后使用简单的数组索引来调用这些函数。这将意味着检索指针并调用函数或根据所使用表的类型跳转到机器代码。
在嵌入式编程中这样做的好处是:
索引比机器代码或指针更有效地利用内存,因此在受限环境中有节省内存的潜力。
对于任何特定功能,索引将保持稳定,更改功能仅需要换出功能指针。
如果这样做确实会花费您一点时间来访问表,但这并不比任何其他虚函数调用都要糟糕。
跳转表(也称为分支表)是一系列指令,所有指令均无条件分支到代码中的另一点。
您可以将它们视为所有情况都已填充的switch(或select)语句:
1 2 3 4 5 6 7 8 9 10 11 12
| MyJump(int c)
{
switch(state)
{
case 0:
goto func0label;
case 1:
goto func1label;
case 2:
goto func2label;
}
} |
请注意,没有返回-跳转到的代码将执行返回,并且它将跳转回到调用myjump的位置。
这对于状态机非常有用,在状态机中您可以根据状态变量执行某些代码。还有许多其他用途,但这是主要用途之一。
它用于您不想浪费时间摆弄堆栈并希望节省代码空间的地方。它尤其适用于速度非常重要的中断处理程序,并且导致中断的外围设备仅由单个变量知道。这类似于带有中断控制器的处理器中的向量表。
一种用途是采用售价为0.60美元的微控制器,并为视频应用生成复合(TV)信号。 micro的功能并不强大-实际上,它的速度还不够快,无法写入每条扫描线。跳转表将用于绘制字符,因为从内存中加载位图花费的时间太长,并使用for()循环将位图推出。取而代之的是,分别跳到字母和扫描行,然后再跳转8条左右的指令,将数据直接直接写入端口。
-亚当
来自维基百科:
In computer programming, a branch
table (sometimes known as a jump
table) is a term used to describe an
efficient method of transferring
program control (branching) to another
part of a program (or a different
program that may have been dynamically
loaded) using a table of branch
instructions. The branch table
construction is commonly used when
programming in assembly language but
may also be generated by a compiler.
A branch table consists of a serial
list of unconditional branch
instructions that is branched into
using an offset created by multiplying
a sequential index by the instruction
length (the number of bytes in memory
occupied by each branch instruction).
It makes use of the fact that machine
code instructions for branching have a
fixed length and can be executed
extremely efficiently by most
hardware, and is most useful when
dealing with raw data values that may
be easily converted to sequential
index values. Given such data, a
branch table can be extremely
efficient; it usually consists of the
following steps: optionally validating
the input data to ensure it is
acceptable; transforming the data into
an offset into the branch table, this
usually involves multiplying or
shifting it to take into account the
instruction length; and branching to
an address made up of the base of the
table and the generated offset: this
often involves an addition of the
offset onto the program counter
register.
维基百科对此进行了很好的总结:
In computer programming, a branch
table (sometimes known as a jump
table) is a term used to describe an
efficient method of transferring
program control (branching) to another
part of a program (or a different
program that may have been dynamically
loaded) using a table of branch
instructions. The branch table
construction is commonly used when
programming in assembly language but
may also be generated by a compiler.
... Use of branch tables and other raw
data encoding was common in the early
days of computing when memory was
expensive, CPUs were slower and
compact data representation and
efficient choice of alternatives were
important. Nowadays, they are commonly
used in embedded programming and
operating system development.
换句话说,当您的系统内存和/或CPU受到极大限制时(例如在嵌入式平台中经常出现这种情况),它是一种有用的构造。
这里描述了一个跳转表,但是简单来说,它是CPU根据特定条件应跳转到的地址数组。例如,C switch语句通常被实现为跳转表,其中每个跳转条目都将转到特定的" case"标签。
在内存使用率非常高的嵌入式系统中,使用跳转表而不是使用更多内存密集型方法(例如大规模的if-else-if)可以更好地服务于许多构造。
跳转表通常(但非排他性地)用于有限状态机中,以使其成为数据驱动的表。
代替嵌套的开关/案例
1 2 3 4 5 6 7 8 9
| switch (state)
case A:
switch (event):
case e1: ....
case e2: ....
case B:
switch (event):
case e3: ....
case e1: .... |
您可以创建2d数组或函数指针,而只需调用handleEvent[state][event]
跳转表(通常称为分支表)通常仅由机器使用。
编译器在汇编程序中创建所有标签的列表,并将所有标签链接到内存位置。跳转表几乎是功能,变量或标签可能存储在内存中的参考卡。
因此,函数执行时,完成时会跳回到其先前的存储位置或跳至下一个函数,依此类推。
如果您在谈论我的想法,那么您不仅在嵌入式系统中需要它们,而且在任何类型的编译/解释环境中都不需要它们。
Brian Gianforcaro