我遇到一种情况,我必须在实模式下跳转到远地址,我的段值在fs
寄存器和偏移量gs
寄存器,在跳转过程中我必须保持准确的寄存器内容,我想出了一个想法如下,
mov bp, fs
shl ebp, 16
mov bp, gs
jmp ebp
假设bp
, fs
and gs
没有在被调用的目的地中读取,这是我刚刚发现的另一种方式实模式下的 NASM 远跳转/远调用和 ASM 代码约定我可以使用,
push fs
push gs
retf
我想知道我应该使用哪种方法或者是否有其他方法可以实现这一目标?我在 x86 汇编方面没有太多技巧,所以请原谅我的无知。
Regards,
Arka
如果性能很重要,不匹配的调用/返回对会导致性能下降返回地址预测器,导致相当于对该 retf 的分支错误预测并随后返回。 (如果far call/far ret甚至参与其中;他们可能不会,IDK.) 否则这是显而易见的选择。
jmp ebp
是近跳(不会改变cs
)所以这是行不通的。你会使用seg:off
作为 32 位整数,将 EIP 设置为该值,而不是 CS:IP。
你需要一个远跳(jmp ptr16:16
or jmp m16:16
). The ptr16:16
版本要求在指令中编码目标地址(因此它不是间接跳转)。唯一可用的间接(可变目标)远跳转编码具有内存中的段:偏移对,而不是寄存器
mov [mem], fs
mov [mem+2], gs
jmp far [mem]
语法来自https://courses.engr.illinois.edu/ece390/archive/spr2002/books/labmanual/inst-ref-jmp.html
push/push/retf
会明显更小,并且不需要单独的暂存空间,所以它可能更好。如果性能很重要,请从两个方面进行衡量。
The mem
空间可以位于堆栈上,也可以位于静态存储中。但是,如果您在到达目的地时需要特定的堆栈内容,则可能无法在堆栈上留下额外的内容,并且使用堆栈下方的空间并不安全。 (并且您只能使用诸如[bp-4]
,不相对于[sp]
,除非您使用 386 的 32 位寻址模式,例如jmp far [esp+4]
管他呢。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)