1

有没有办法在旧的 Delphi 版本(如 6 或 7)中使用英特尔的 RdRand 操作码?

也许使用

asm db $...结束;

或者其他的东西?如何将数字存储到变量中?

速度非常重要。我不能为此使用外部库。

4

1 回答 1

3

由于我的处理器不支持 RdRand,因此我无法对此进行测试,但这应该可以帮助您:

function RdRand: Cardinal;
asm
  db  $0f
  db  $c7
  db  $f0
end;

RdRand 的操作码是 0x0f 0xc7,ModR/M 值0xf0将输出放入函数返回值 EAX。

现在,这是不完整的。您还必须检查进位标志的值以确定 RdRand 执行是否成功

调用 RDRAND 指令后,调用者必须检查进位标志 (CF) 以确定在执行 RDRAND 指令时是否有可用的随机值。如表 3 所示,值 1 表示随机值可用并放置在调用中提供的目标寄存器中。值 0 表示随机值不可用。在当前架构中,目标寄存器也将作为这种情况的副作用归零。

因此,这可能会导致您编写如下代码:

function TryRdRand(out Value: Cardinal): Boolean;
asm
  db   $0f
  db   $c7
  db   $f1
  jc   @success
  xor  eax,eax
  ret
@success:
  mov  [eax],ecx
  mov  eax,1
end;

我再次无法测试它,但我希望它可以帮助你。0xf1 的 ModR/M 将输出值放入 ecx,如果操作成功,我将其复制到 [eax] 中。

上面链接的文档接着说:

建议应用程序在紧密循环中尝试 10 次重试,以防万一 RDRAND 指令不返回随机数。这个数字基于二项式概率论:给定 DRNG 的设计余量,连续 10 次故障的可能性很小,实际上表明 CPU 问题更大。

您可以在上述功能之上轻松实施此重试策略。

最后,我确定您知道,但您必须调用 CPUID 以检查处理器是否支持 RdRand。

于 2015-02-16T10:20:32.807 回答