2

我有一种情况,我必须在实模式下跳转到远地址,我在寄存器中有段值,在fs寄存器中有偏移量gs,在跳转期间我必须保持准确的寄存器内容,我想出了一个想法下列的,

mov bp, fs
shl ebp, 16
mov bp, gs
jmp ebp

假设bpfs并且gs没有在被调用的目标中读取,这是我刚刚在实模式下的 NASM 远跳转/远调用和 ASM 代码约定中找到的另一种方式,我可以使用,

push fs
push gs
retf

我想知道我应该使用哪种方法,或者是否有其他方法可以实现这一点?我在x86组装方面没有太多技能,所以请原谅我的无知。

问候,

阿尔卡

4

1 回答 1

1

如果性能很重要,不匹配的调用/返回对会抛出返回地址预测器,导致等效于此 retf 上的分支错误预测并随后返回。(如果 far call / far ret 甚至参与其中;他们可能不会,IDK。)否则这是显而易见的选择。

jmp ebp是一个近跳(不改变cs),所以不能工作。您将使用seg:off32 位整数,将 EIP 设置为该值,而不是 CS:IP。

您需要跳远(jmp ptr16:16jmp m16:16)。该ptr16:16版本要求在指令中对目标地址进行编码(因此它不是间接跳转)。唯一可用的间接(可变目标)远跳转编码具有内存中的段:偏移量对,而不是(a)寄存器

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会明显更小,并且不需要单独的暂存空间,所以它可能会更好。如果性能很重要,请双向衡量。

mem空间可以在堆栈上,也可以在静态存储上。但是,如果您在到达目的地时需要特定的堆栈内容,您可能无法在堆栈上留下额外的东西,并且使用堆栈下方的空间也不安全。(你只能使用寻址模式来寻址堆栈[bp-4],而不是相对于[sp],除非你在 386 上使用 32 位寻址模式jmp far [esp+4]或其他。)

于 2015-08-11T14:24:34.833 回答