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.
Interesting point that it's a guaranteed one-instruction way to raise #DE
without requiring any instructions to put values in register, though.
(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).
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).
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
?
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…