2017-11-10 156 views
0

所以我想了解TBB如何在Assembly中为switch语句工作。我看到它是如何写在教科书/在线手册中的,但我不明白偏移量在分支表中如何工作。 它如何从分支表转换为指令?如何扣除标签以获得正确的偏移量,以及为什么除以2?ARM大会TBB指令 - 跳跃是如何工作的?

以我教科书它说

到的程序应该 分支如下计算该指令的存储器地址:
目标= PC + 4 +( 2 * BranchTable [R0] )

其中r0是包含分支表内偏移量的计数器。在TBB,PC已经指向下一条指令(分支表,PC = PC + 4)。据推测,分支表将第二个偏移量加载到正确的指令(2 * BranchTable [r0])。从我在课本和在线上看到的分支表标签从指令标签中扣除。这应该给一个类似4n的偏移量。为什么用2除?谢谢!

编辑:做了一些数学

所以我做了一些数学和事实证明,该分支表偏移量为[(LABEL2 - LABEL1)/ 2]。之前插入等式给出target = PC + 4 +(标签2 - 标签)。这是有道理的,但我仍然想知道是否有人有理由,或者如果我的逻辑错误 - 为什么TBB设置除以2 /乘以差异2?

+2

由于指令地址总是即使是这样,缩放2倍也是有意义的,所以你会得到两倍的范围。另一种看待它的方式是存储偏移量的#1-8位,而位#0隐含为零,即二进制中的“XXXXXXXX0”。 – Jester

+0

这很有道理。我记得读到PC一直因为对齐而将位[1:0]设置为0(不记得是16位还是32位指令......)。这也是为什么DCB指令通常跟着ALIGN?对不起,你能澄清一下范围部分吗? – Pablo

+0

这是32位。至于'DCB',是的。该手册说:_“如果DCB后面跟着一条指令,请使用ALIGN指令来确保指令对齐。”_('DCB'是指令,而不是指令)。你可以使用的范围是512个字节而不是256个,如果你天真地使用了一个字节偏移量,你就可以使用这个范围。 – Jester

回答

0

TBB/TBH仅在Thumb2模式下可用。

ARM Thumb2指令始终以偶数地址开始。能够分支到PC+4 + {0, 2, 4, 6, 8, ..., 508, 510}
PC+4 + {0, 1, 2, 3, 4, ..., 254, 255 }更有用,因为所有的奇数偏移都是无用的。 As @Jester explained in the first comment,乘以2会使您获得两倍于单字节偏移量的范围,而不会损失灵活性。

ARM的设计人员可能已经设计它始终乘以4,但512B通常是足够的范围,并且它有时需要填充代码块为4个字节长的倍数。如果需要更大的偏移量,则TBH使用半字16位偏移量(仍然乘以2)。

下面是使用TBB,与原十六进制跳转表的一个真实的例子,并评论拆卸工作了各分支目标是如何达成的数学(如
case 3: (0x3164 + 0x9 * 2)): Confused by TBB in a section of ARM disassembly