Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the i386 instruction "div ah" pointless?

Tags:

x86

assembly

i386

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

    ...
    temp ← AX / SRC;
    IF temp > FFH
        THEN #DE; (* Divide error *)
        ELSE
            AL ← temp;
            AH ← AX MOD SRC;
    FI;
    ...

For div ah the SRC would be ah. IMHO temp will always be larger than FFH and therefore the exception will be raised since:

  1. AX = 256*AH+AL
  2. temp = AX / AH = (256*AH+AL)/AH = 256 + AL/AH
  3. temp is over FFH

Do I miss something here?

like image 601
rfalke Avatar asked Aug 05 '20 21:08

rfalke


1 Answers

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.

like image 83
Peter Cordes Avatar answered Oct 06 '22 09:10

Peter Cordes