问题描述
来自 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
,因此将引发异常,因为:
For div ah
the SRC
would be ah
. IMHO temp
will always be larger than FFH
and therefore the exception will be raised since:
- AX = 256*AH+AL
- 温度 = AX/AH = (256*AH+AL)/AH = 256 + AL/AH
- 温度已过
FFH
我错过了什么吗?
推荐答案
没错,就像 div edx
一样,它永远无法在没有故障的情况下使用.2N/N的标准=>N 位 div
没有溢出其商是 high_half(dividend) ,如您所示,因此使用
divisor = high(dividend)
将始终溢出(或除以零).为什么DIV EDX"在 MASM 中总是产生处理器异常? 以另一种方式解释同样的事情.
That's correct, just like div edx
it's never usable without faulting. The criterion for 2N/N => N-bit div
not overflowing its quotient is high_half(dividend) < divisor
, as you showed, so using divisor = high(dividend)
will always overflow (or divide by zero). Why "DIV EDX" in MASM always generates processor exception? explains the same thing another way.
有趣的一点是,它是一种有保证的单指令方式来提高 #DE
而不需要任何指令来将值放入寄存器.
Interesting point that it's a guaranteed one-instruction way to raise #DE
without requiring any instructions to put values in register, though.
(在保护模式下,int 0
不是完全一样的东西.例如在 Linux 下,在用户空间 int 0
将 #GP
-> SIGSEGV 因为对 IDT 条目的权限,而实际的除法异常将 #DE
-> SIGFPE).
(In protected mode, int 0
is not exactly the same thing. e.g. under Linux, in user-space int 0
will #GP
-> SIGSEGV because of permissions on the IDT entry, while an actual divide exception will #DE
-> SIGFPE).
正如 Jester 指出的那样,该编码仅占 F6/6 div r/m8
的 2^5 种可能编码中的一种,仅计算 ModRM 字节(不是额外字节的巨大可能性寻址模式可以使用).
As Jester points out, that encoding only accounts for 1 of the 2^5 possible encodings of F6 /6 div r/m8
, counting just the ModRM byte (not the vast possibilities of extra bytes that addressing modes can use).
使其不可编码会在解码器中使用额外的晶体管.然后你如何处理这个 2 字节的序列?#UD
非法指令异常?这很愚蠢,让它在正常解码并像任何其他 div
指令一样进入执行单元后引发 #DE
.或者将它用于其他一些特殊的东西,比如 mfence
?
Making it not-encodeable would take extra transistors in the decoders. And then what do you do with that 2-byte sequence? #UD
illegal instruction exception? That's silly, just let it raise #DE
after decoding normally and getting to the execution unit like any other div
instruction. Or use it for some other special thing like mfence
?
让 div ah
的 2 字节机器代码实际上意味着一些完全不同的单指令,这可能不是一个明智的设计决定.无论如何,那艘船以 8086 航行,在那里它将升起 #DE
,而不是 #UD
;任何更改都会破坏向后兼容.由于为新操作码寻找新编码空间的侵入性较少(例如 lds
和 les
或任何 VEX 前缀借用的非法编码),Intel 和 AMD 还没有屈服于这种疯狂.那些 LES/LDS 32 位模式编码已经引发 #ud
而不是另一个例外,更重要的是有更多的备用位,因此 VEX 前缀有空间实际编码那些 2 或 3 字节中的某些字段前缀.
It probably wouldn't really have been a sensible design decision to have the 2-byte machine code for div ah
actually mean some totally different single instruction. In any case, that ship sailed with 8086 where it will raise #DE
, not #UD
; any change would break that backwards compat. Since there are less intrusive ways to find new coding-space for new opcodes (e.g. like the illegal encodings of lds
and les
or whatever that VEX prefixes borrow), Intel and AMD haven't yet stooped to such insanity. Those LES / LDS 32-bit-mode encodings already raised #ud
instead of another exception, and more importantly had more spare bits so the VEX prefixes have room to actually encode some fields in those 2 or 3 byte prefixes.
这篇关于i386指令是“div啊"吗?无意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!