i386 指令“div ah”毫无意义吗?

rfa*_*lke 8 x86 assembly i386

https://www.felixcloutier.com/x86/div

    ...
    temp ? AX / SRC;
    IF temp > FFH
        THEN #DE; (* Divide error *)
        ELSE
            AL ? temp;
            AH ? AX MOD SRC;
    FI;
    ...
Run Code Online (Sandbox Code Playgroud)

对于div ahSRCah。恕我直言,temp将始终大于FFH,因此将引发异常,因为:

  1. AX = 256*AH+AL
  2. 温度 = AX / AH = (256*AH+AL)/AH = 256 + AL/AH
  3. 温度结束 FFH

我在这里想念什么吗?

Pet*_*des 9

这是正确的,就像div edx它永远无法在没有故障的情况下使用一样。2N/N => N 位div不溢出其商的标准是high_half(dividend) < divisor,如您所示,因此 usingdivisor = high(dividend)将始终溢出(或除以零)。 为什么 MASM 中的“DIV EDX”总是产生处理器异常?用另一种方式解释同样的事情。

有趣的一点是,它是一种有保证的单指令方式,#DE无需任何指令将值放入寄存器中。

(在保护模式下,int 0完全一样的东西例如在Linux下,在用户空间。int 0#GP- >因为在IDT项权限的SIGSEGV,而实际的鸿沟异常会#DE- > SIGFPE)。


正如 Jester 指出的那样,该编码仅占 2^5 种可能编码中的 1 种F6 /6 div r/m8,仅计算 ModRM 字节(不是寻址模式可以使用的额外字节的巨大可能性)。

使其不可编码将需要在解码器中使用额外的晶体管。然后你如何处理这个 2 字节的序列? #UD非法指令异常?这很愚蠢,只是让它#DE在正常解码并像任何其他div指令一样进入执行单元后升高。或者将它用于其他一些特殊的事情,例如mfence

让 2 字节机器代码div ah实际上意味着一些完全不同的单指令可能并不是一个明智的设计决定。无论如何,那艘船以 8086 航行,它将升起#DE,而不是#UD;任何更改都会破坏向后兼容。由于为新操作码寻找新编码空间的方法较少(例如非法编码lds和/les或 VEX 前缀借用的任何东西),英特尔和 AMD 还没有屈服于这种疯狂。那些 LES / LDS 32 位模式编码已经提出#ud而不是另一个例外,更重要的是有更多的空闲位,因此 VEX 前缀有空间实际编码那些 2 或 3 字节前缀中的某些字段。