i386 指令 "div ah" 没有意义吗?
Is the i386 instruction "div ah" pointless?
来自https://www.felixcloutier.com/x86/div:
...
temp ← AX / SRC;
IF temp > FFH
THEN #DE; (* Divide error *)
ELSE
AL ← temp;
AH ← AX MOD SRC;
FI;
...
对于 div ah
,SRC
将是 ah
。恕我直言 temp
将始终大于 FFH
因此将引发异常,因为:
- AX = 256*AH+AL
- 温度=AX/AH=(256*AH+AL)/AH=256+AL/AH
- 温度结束
FFH
我是不是漏掉了什么?
这是正确的,就像 div edx
它永远不会在没有错误的情况下使用。 2N/N => N-bit div
不溢出其商的标准是 high_half(dividend) < divisor
,如您所示,因此使用 divisor = high(dividend)
将始终溢出(或除以零)。 Why "DIV EDX" in MASM always generates processor exception? 用另一种方式解释同样的事情。
有趣的一点是,这是一种保证 one-instruction 提高 #DE
的方法,但不需要任何指令将值放入寄存器。
(在保护模式下,int 0
与 不是 完全相同的东西。例如在 Linux 下,在 user-space int 0
将 #GP
-> SIGSEGV 因为 IDT 条目的权限,而实际除法异常将 #DE
-> SIGFPE).
正如 Jester 指出的那样,该编码仅占 F6 /6 div r/m8
的 2^5 种可能编码中的一种,仅计算 ModRM 字节(不包括寻址模式可以使用的额外字节的大量可能性)。
使其成为 not-encodeable 需要解码器中的额外晶体管。然后你如何处理这个 2 字节的序列? #UD
非法指令异常?这很愚蠢,只是让它在正常解码后引发 #DE
并像任何其他 div
指令一样进入执行单元。或者将它用于其他一些特殊的事情,例如 mfence
?
div ah
的 2 字节机器代码实际上意味着一些完全不同的单指令,这可能并不是一个明智的设计决定。无论如何,那艘船以 8086 航行,它将升起 #DE
,而不是 #UD
;任何更改都会破坏向后兼容。由于为新操作码(例如 the illegal encodings of lds
and les
or whatever that VEX prefixes borrow)寻找新 coding-space 的侵入性较小的方法,Intel 和 AMD 还没有屈服于这种疯狂。那些 LES / LDS 32-bit-mode 编码已经引发了 #ud
而不是另一个异常,更重要的是有更多的备用位,所以 VEX 前缀有空间实际编码那些 2 或 3 字节前缀中的一些字段。
来自https://www.felixcloutier.com/x86/div:
...
temp ← AX / SRC;
IF temp > FFH
THEN #DE; (* Divide error *)
ELSE
AL ← temp;
AH ← AX MOD SRC;
FI;
...
对于 div ah
,SRC
将是 ah
。恕我直言 temp
将始终大于 FFH
因此将引发异常,因为:
- AX = 256*AH+AL
- 温度=AX/AH=(256*AH+AL)/AH=256+AL/AH
- 温度结束
FFH
我是不是漏掉了什么?
这是正确的,就像 div edx
它永远不会在没有错误的情况下使用。 2N/N => N-bit div
不溢出其商的标准是 high_half(dividend) < divisor
,如您所示,因此使用 divisor = high(dividend)
将始终溢出(或除以零)。 Why "DIV EDX" in MASM always generates processor exception? 用另一种方式解释同样的事情。
有趣的一点是,这是一种保证 one-instruction 提高 #DE
的方法,但不需要任何指令将值放入寄存器。
(在保护模式下,int 0
与 不是 完全相同的东西。例如在 Linux 下,在 user-space int 0
将 #GP
-> SIGSEGV 因为 IDT 条目的权限,而实际除法异常将 #DE
-> SIGFPE).
正如 Jester 指出的那样,该编码仅占 F6 /6 div r/m8
的 2^5 种可能编码中的一种,仅计算 ModRM 字节(不包括寻址模式可以使用的额外字节的大量可能性)。
使其成为 not-encodeable 需要解码器中的额外晶体管。然后你如何处理这个 2 字节的序列? #UD
非法指令异常?这很愚蠢,只是让它在正常解码后引发 #DE
并像任何其他 div
指令一样进入执行单元。或者将它用于其他一些特殊的事情,例如 mfence
?
div ah
的 2 字节机器代码实际上意味着一些完全不同的单指令,这可能并不是一个明智的设计决定。无论如何,那艘船以 8086 航行,它将升起 #DE
,而不是 #UD
;任何更改都会破坏向后兼容。由于为新操作码(例如 the illegal encodings of lds
and les
or whatever that VEX prefixes borrow)寻找新 coding-space 的侵入性较小的方法,Intel 和 AMD 还没有屈服于这种疯狂。那些 LES / LDS 32-bit-mode 编码已经引发了 #ud
而不是另一个异常,更重要的是有更多的备用位,所以 VEX 前缀有空间实际编码那些 2 或 3 字节前缀中的一些字段。