【问题标题】:Jumping to a far address in real mode在实模式下跳转到远地址
【发布时间】:2015-11-03 19:30:17
【问题描述】:

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

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

假设bpfsgs没有在被调用的目的地中读取,另一种我刚刚在NASM far jump / far call in real mode and ASM code conventions中找到并且我可以使用的方式,

push fs
push gs
retf

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

问候,

阿尔卡

【问题讨论】:

    标签: assembly x86 x86-16 real-mode memory-segmentation


    【解决方案1】:

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

    jmp ebp 是一个近跳(不会改变cs),所以它不能工作。您将使用 seg:off 作为 32 位整数,将 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 上使用像 jmp far [esp+4] 这样的 32 位寻址模式。)

    【讨论】:

      猜你喜欢
      • 2013-02-21
      • 2016-08-15
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      相关资源
      最近更新 更多