本文介绍了i386指令是“div啊"吗?无意义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自 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 ahSRC 将是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:

  1. AX = 256*AH+AL
  2. 温度 = AX/AH = (256*AH+AL)/AH = 256 + AL/AH
  3. 温度已过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;任何更改都会破坏向后兼容.由于为新操作码寻找新编码空间的侵入性较少(例如 ldsles 或任何 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啊"吗?无意义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 05:37