如何在一次通过中选择跳转指令?

时间:2018-10-15 22:50:06

标签: algorithm assembly optimization

可变长度指令集通常提供具有不同大小位移的多个跳转指令,以优化代码的大小。例如,PDP-11兼有

0004XX       BR FOO      # branch always, 8 bit displacement

000167 XXXXX JMP FOO     # jump relative, 16 bit displacement

表示相对跳跃。在最近的示例中,8086兼有

EB XX        JMP FOO     # jump short, 8 bit displacement

E8 XX XX     JMP FOO     # jmp near, 16 bit displacement

可用。

汇编器不应让程序员猜测使用正确的跳转类型;它应该能够推断出最短的编码,以便所有跳转都能达到目标。当您考虑必须模拟具有大位移的跳跃的情况时,此优化尤为重要。例如,8086缺少16位位移的条件跳转。对于这样的代码:

74 XX        JE FOO      # jump if equal, 8 bit displacement

如果FOO距离太远,汇编器应发出如下代码:

75 03        JNE AROUND  # jump if not equal
E8 XX XX     JMP FOO     # jump near, 16 bit displacement
     AROUND: ...

由于此代码的时间是JE的两倍,因此,仅在绝对必要时才应发出它。

一种简单的方法是首先尝试以最小的位移来组装所有的弹跳。如果有任何不适合的跳转,则汇编器将执行另一遍操作,其中所有以前不适合的跳转都将替换为更长的跳转。反复进行此操作,直到所有跳跃都适合为止。虽然易于实现,但该算法的运行时间为O(n²),有点黑。

是否有更好的(最好是线性时间)算法来确定理想的跳转指令?

another question中所述,从适当的高级构造开始,这种 start small 算法不一定是最佳算法。我想假设以下约束条件:

  • 在选择指令时已经发生了条件性的代码包含和宏扩展,并且不受这些决定的影响
  • 如果数据对象的大小受两个显式或隐式标签之间的距离影响,则大小随距离单调增长。例如,写是合法的

             .space foo-bar
    

    如果bar不在foo之前出现。

  • 违反先前的约束,可能存在对齐指令

0 个答案:

没有答案