我有一种情况,我必须在实模式下跳转到远地址,我有fs
寄存器中的段值和gs
寄存器中的偏移量,并且在跳转期间我必须维护确切的注册内容,我提出了以下一个想法,
mov bp, fs
shl ebp, 16
mov bp, gs
jmp ebp
假设bp
,fs
和gs
未在被叫目的地中被读取,这是我在NASM far jump / far call in real mode and ASM code conventions找到的另一种方式,我可以使用,
push fs
push gs
retf
我想知道我应该使用哪种方法,或者是否有其他方法可以实现这一目标?我在x86汇编方面没有太多技巧,所以请原谅我的无知。
此致
阿尔卡
答案 0 :(得分:0)
如果性能很重要,不匹配的调用/返回对会抛弃返回地址预测器,导致相当于分支错误预测。
我认为远程跳转需要更改代码段寄存器。英特尔的手册说任何类型的近跳(例如jmp ebp
)都不会改变cs
。你需要一个远程跳跃(jmp ptr16:16
或jmp m16:16
)。 ptr16:16
版本要求在指令中编码目标地址(因此它不是间接跳转)。
唯一可用的间接(可变目的地)远程跳转编码在内存中具有segment:offset对,而不是寄存器。
mov [mem], fs
mov [mem+2], gs
jmp far [mem] # not sure about syntax
语法来自 https://courses.engr.illinois.edu/ece390/archive/spr2002/books/labmanual/inst-ref-jmp.html
如果代码大小比此代码片段的性能更重要,push/push/retf
将显着缩小,并且不需要单独的临时空间。