x86 程序集 16 位相对调用

x86 Assembly 16-bit Relative Call

我注意到以下两条汇编指令在 x86 中可用:

E8 cw    CALL rel16
E8 cd    CALL rel32

我对指令处理器如何区分这两个调用感到困惑。我唯一能想到的是,如果应用程序是 16 位,则 IP 假定为前者,如果应用程序是 32 位,则 IP 假定为后者。我的解释是否正确,或者是否有办法将 CALL rel16 编码为 32 位应用程序?

此答案由 Michael Petch 在问题的评论中提供:

The operand size (which determines whether it is rel16 or rel32) has a different default size depending on the mode of the processor (realmode/32-bit protected mode/16-bit protected mode/64-bit long mode/V8086 mode etc). You can see this chart for details. You can override the default with a 0x66 operand prefix. In 32-bit mode you can use 0x66 instruction prefix to change default from 32-bit operand size to 16-bit.

我注意到在使用这条指令时,EIP 的高 16 位被清零了。因此,0x66 0xE8 16 位相对调用具有以下 C++ 语义:

int16_t offset = ...;
EIP = (EIP + offset) & 0xFFFF;

是的,可以在 32 位应用程序中使用 16 位相对调用指令。