[底部加粗的问题]
当汇编程序生成二进制编码时,它需要决定是使每个分支变长还是短,如果可能的话,短路更好.汇编程序的这一部分称为分支位移优化(BDO)算法.一种典型的方法是汇编程序使所有分支编码变短(如果它们小于某个阈值),然后迭代地增加任何分支跳转到未到达的long.当然,这可以导致其他分支转换为跳远.因此,汇编程序必须不断通过跳转列表,直到不再需要升迁.这种二次时间方法对我来说似乎是一种最优算法,但据推测BDO是NP完全的,这种方法实际上并不是最优的.
兰德尔海德提供了一个反例:
.386
.model flat, syscall
00000000 .code
00000000 _HLAMain proc
00000000 E9 00000016 jmpLbl: jmp [near ptr] target
00000005 = 00000005 jmpSize = $-jmpLbl
00000005 00000016 [ byte 32 - jmpSize*2
dup
(0)
00
]
0000001B target:
0000001B _HLAMain endp
end
Run Code Online (Sandbox Code Playgroud)
通过在括号"[near ptr]"中添加部分并强制进行5字节编码,二进制实际上最终会变短,因为分配的数组比跳跃大小的两倍小.因此,通过使跳转编码更短,最终代码实际上更长.
这对我来说似乎是一个非常病态的情况,并不是真正相关的,因为分支编码仍然较小,它只是对程序的非分支部分的这种奇怪的副作用,导致二进制变大.由于分支编码本身仍然较小,我并不认为这是"开始小"算法的有效反例.
我可以将start-small算法视为最佳BDO算法,还是存在一个实际情况,即它不能为所有分支提供最小的编码大小?
我正在查看一些用于汇编的练习代码,并且赋值基本上是用另一个跳转点替换.
原始jmp是SHORT jmp,使用此指令无法到达我需要接近的终点.
我现在有三个选项,我要么删除'SHORT',要么插入'LONG'或者我插入'FAR'.
如果有任何文件指出它们之间的差异,我还没有找到它.任何人都可以在这里帮助吗?