32位模式下指令解码器如何区分EVEX前缀与BOUND操作码?
在32位模式下,指令解码器如何区分EVEX前缀与BOUND操作码?兼谈VEX前缀与LDS/LES指令的冲突解决
好问题!在32位x86架构下,指令解码器要区分这些看似重叠的操作码和前缀,靠的是利用指令格式的固有规则,咱们一步步拆解:
一、区分EVEX前缀与BOUND操作码
BOUND指令的操作码是62h,而EVEX前缀的起始字节也是62h,两者在32位模式下共存,解码器主要靠后续字节的格式约束来区分:
- BOUND指令的作用是检查寄存器中的值是否在内存存储的上下界范围内,它的格式要求必须包含一个内存操作数,因此紧跟
62h的ModRM字节的mod字段绝对不能是11b(11b表示操作数是寄存器,不符合BOUND的指令语义)。 - EVEX前缀是AVX-512指令的前缀,它的后续字节(包括EVEX扩展字节和后续的ModRM)会包含AVX指令特有的编码规则:比如EVEX前缀的第二个字节有特定的位标识,或者后续的ModRM允许mod字段为11b(因为AVX指令支持寄存器到寄存器的操作)。
解码器遇到62h时,会先检查后续字节的结构:如果符合EVEX前缀的编码特征(比如存在EVEX的特定位,或者ModRM的mod为11b),就判定为EVEX前缀;否则就按照BOUND指令来解析。
二、解决VEX前缀与LDS/LES指令的冲突
VEX前缀的起始字节C4h、C5h正好和LDS(C5h)、LES(C4h)的操作码完全重合,这俩指令在64位模式下被移除,但32位模式下仍有效,英特尔靠两个关键点解决歧义:
- 利用ModRM字段的约束
合法的LDS/LES指令必须从内存中加载段选择器和偏移量到寄存器,因此它们的ModRM字节的mod字段不能为11b(11b表示源操作数是寄存器,而LDS/LES不允许源是寄存器)。而VEX前缀的设计正好利用了这一点:当解码器遇到C4h/C5h时,如果后续ModRM的mod字段是11b,直接判定为VEX前缀;如果mod不是11b,再进一步验证是否符合LDS/LES的指令格式。 - 反转寄存器扩展的高位
为了进一步避免歧义(比如某些极端情况下ModRM的mod不是11b,但实际是VEX前缀),英特尔在VEX前缀的寄存器编码中反转了寄存器扩展位的高位。LDS/LES的寄存器编码是标准格式,而VEX前缀的寄存器编码有这个反转特征,解码器可以通过这一点来区分两者。
内容的提问来源于stack exchange,提问作者phuclv
相关产品推荐
相关产品推荐

