关于相对跳跃,我有以下问题:
- 我知道这
JMP SHORT <displacement>
将跳转到<displacement>
相对于当前 PC 的字节。那是对的吗? - 汇编器是否会自动生成相对跳转的操作码?即当我刚刚写的时候
JMP <label>
,如果该标签位于当前PC 128 字节之外,它会产生相对跳转? - 如果我确实想使用
JMP SHORT <displacement>
,计算位移的正确方法是什么?通过检查列表文件并计算偏移量?
每个汇编器(程序)和汇编器的每个版本都可以选择默认为长或短。因此,我不会寻找所有汇编程序默认为一件事的笼统声明。如果好奇,试试看会发生什么。
使用 x86 和可变长度指令,简单地编写位移代码将非常棘手,必须提醒自己永远不要接触跳转和目标之间的代码。
是的,我首先让汇编器使用标签对指令进行编码,然后获取指令集参考手册和带有地址的反汇编,并弄清楚如何计算位移。如果汇编器允许您自己设置位移,这可能是汇编器特定的东西,并且您需要知道它可能需要该位移的单位。x86 可能是字节,但是固定字长指令集可能必须以指令为单位而不是字节来给出位移。或字节不是指令,所以我会使用位移然后再次反汇编以查看它计算了正确的指令。
假设汇编器自动使用短编码或普通编码。乍一看,如果可能,总是切换到短编码似乎没问题,但实际上有可能这样做,以便必须再次将其他一些分支更改为长编码。
例如(未经测试或任何东西,只是为了得到这个想法):
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 点很难,有很多不同的方法可以解决这个问题。例如采用显式“短”修饰符,显式“长”修饰符,进行安全猜测并最终得到在极少数情况下不需要的长版本等。