关于相对跳跃,我有以下问题:
JMP SHORT <displacement>
将相对于当前PC跳转到<displacement>
个字节。这是对的吗?JMP <label>
时,如果该标签位于当前PC的128个字节之内,它将产生相对跳跃?JMP SHORT <displacement>
,计算位移的正确方法是什么?通过检查列表文件并计算偏移量?答案 0 :(得分:5)
每个汇编程序(程序)和汇编程序的每个版本都可以选择默认为long或short。因此,我不会寻找一个全面的声明,所有汇编程序都默认为一件事。如果好奇,试试看看会发生什么。
使用x86和可变长度指令,简单地编码位移是非常棘手的,必须提醒自己永远不要触摸跳转和目标之间的代码。
是的,我首先让汇编程序使用标签对指令进行编码,然后获取指令集参考手册和带地址的反汇编,并弄清楚如何计算位移。如果汇编程序允许您自己设置位移,这可能是汇编程序特定的事情,您需要知道它可能需要该位移的单位。 x86可能是字节,但固定字长指令集可能必须以指令为单位给出位移而不是字节。或字节不是指令,所以我会使用置换然后再次反汇编,看它计算出正确的指令。
答案 1 :(得分:2)
假设汇编程序自动使用短编码或普通编码。乍一看,如果可能的话,总是可以切换到短编码似乎没问题,但实际上可以做到这一点,以便其他分支必须再次更改为长编码。
例如(没有测试或任何东西,只是为了得到这个想法):
jmp _skip ; relative offset depends on
the size of "other code", which may include other jumps
; other code
_skip:
所以你不能做一个“前进”传球来确定尺寸 - 当你在跳跃时,你还不知道它是否适合,因为你还没有决定如何处理其他的跳跃。
然后呢? (没有测试或任何东西,只是为了得到这个想法)
.fill 124
jmp _somewhere ; 2 bytes, or 5?
jmp _quiteFarAway ; relative offset is either 130 or 127
.align 256
_quiteFarAway:
不,也不能做向后传递,当决定跳转到_quiteFarAway的编码时你还不知道它是否适合,因为你还没有决定如何处理其他跳跃。
做到第2点很难,有很多不同的方法可以解决这个问题。这样做了一个明确的“短”修饰符,一个明确的“长”修饰符,进行安全猜测并最终得到了在极少数情况下不需要的长版本等。