我注意到x86中提供了以下两个汇编指令:
E8 cw CALL rel16
E8 cd CALL rel32
我很困惑指令处理器如何区分这两个调用。我唯一能想到的是,如果应用程序是16位,则IP假定是前者,而如果应用程序是32位,则IP假定是后者。我的解释正确吗,还是有办法将CALL rel16
编码为32位应用程序?
答案 0 :(得分:1)
此答案由 Michael Petch 在问题的评论中提供:
操作数大小(确定是rel16还是rel32)具有不同的默认大小,具体取决于处理器的模式(实模式/ 32位保护模式/ 16位保护模式/ 64位长模式/ V8086)模式等)。您可以看到this chart for details。您可以使用0x66操作数前缀覆盖默认值。在32位模式下,可以使用0x66指令前缀将默认值从32位操作数大小更改为16位。
我注意到使用此指令时EIP的高16位被清零。因此,0x66 0xE8
16位相对调用具有以下C ++语义:
int16_t offset = ...;
EIP = (EIP + offset) & 0xFFFF;
是的,可以在32位应用程序中使用16位相对调用指令。