可变长度指令集通常提供具有不同大小位移的多个跳转指令,以优化代码的大小。例如,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
之前出现。