在x86汇编中,为什么当分子来自RDRAND时DIV会抛出异常?

问题描述 投票:0回答:1

我多年来一直在编写 x86 Assembly,但从未遇到过这个。我希望有人能给我指出正确的方向,这样我就可以“Doh!”时刻。

在伪代码中,当我写

42 DIV 4
时,除法按预期工作。当我写
RDRAND DIV 4
时,CPU抛出异常。我正在做无符号的 16 位算术,但我也以 32 和 64 位重现了它。

我已经在 Intel Xeon 和 Core CPU 以及 AMD EPYC 上重现了这一点...所以我认为这是故意的,而不是孤立的事情。

这是源代码。我是这样编译的:

clang -masm=intel -o div_bug div_bug.c

#include <stdio.h>
#include <stdint.h>

int main() {
   printf( "div_bug\n" );

   uint8_t rval;

   // rdrand sets CF on success... I've tried this with and without this 
   // check and the program still throws an exception

   // This works as expected
   asm volatile (
//     "try_again_1:"
       "rdrand ax;"           // If CF==0, then the rdrand failed... try again
//     "jnc    try_again_1;"
       "mov    ax, 42;"       // This works... as expected
       "mov    cl, 4;"
       "div    cl;"
       "mov    %0, ah;"
      :"=r" ( rval )          // Output
      :                       // Input
      :"ax", "cl", "cc"   );  // Clobbers

   printf( "The first return value is %u\n", rval );


   // This throws a `Floating point exception (core dumped)`
   asm volatile (
//     "try_again_2:"
       "rdrand ax;"           // If CF==0, then the rdrand failed... try again
//     "jnc    try_again_2;"
//     "mov    ax, 42;"       // <---- Remove this and it breaks
       "mov    cl, 4;"
       "div    cl;"
       "mov    %0, ah;"
      :"=r" ( rval )          // Output
      :                       // Input
      :"ax", "cl", "cc"   );  // Clobbers

   printf( "The second return value is %u\n", rval );

}

我还在这里获得了代码仓库:https://github.com/marknelsonengineer/div_bug.git

我研究了Intel SDM中的

DIV
RDRAND
指令,但没有看到任何明显的东西。

我期望

RDRAND
返回一个数字...我可以除以 4。

我的问题是:当分子来自

DIV
时,为什么
RDRAND
会抛出异常?

谢谢你, 马克

c assembly x86 inline rdrand
1个回答
0
投票

大多数时候你的随机数> = 1024,这意味着除以4的结果无法容纳在8位中,并且你会得到一个#DE执行。来自描述 DIV 的 Intel 手册:

IF OperandSize = 8 (* Word/Byte Operation *)
    THEN
        temp ← AX / SRC;
        IF temp > FFH
            THEN #DE; (* Divide error *)
        ELSE
            AL ← temp;
            AH ← AX MOD SRC;
        FI;
FI;
© www.soinside.com 2019 - 2024. All rights reserved.