在 Delphi 6/7 中使用英特尔的 RdRand 操作码

Using Intel's RdRand opcode in Delphi 6/7

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

也许使用

asm 数据库 $... 结束;

还是什么?如何将数字存储到变量中?

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

我无法对此进行测试,因为我的处理器不支持 RdRand,但这应该能让你继续:

function RdRand: Cardinal;
asm
  db  [=10=]f
  db  $c7
  db  $f0
end;

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

现在,这还不完整。您还必须 check the value of the carry flag to determine whether or not the RdRand execution succeeded

After invoking the RDRAND instruction, the caller must examine the carry flag (CF) to determine whether a random value was available at the time the RDRAND instruction was executed. As Table 3 shows, a value of 1 indicates that a random value was available and placed in the destination register provided in the invocation. A value of 0 indicates that a random value was not available. In current architectures the destination register will also be zeroed as a side effect of this condition.

所以这可能会导致您编写如下代码:

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

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

上面的链接文档接着说:

It is recommended that applications attempt 10 retries in a tight loop in the unlikely event that the RDRAND instruction does not return a random number. This number is based on a binomial probability argument: given the design margins of the DRNG, the odds of ten failures in a row are astronomically small and would in fact be an indication of a larger CPU issue.

您可以轻松地在上述函数之上实施此重试策略。

最后,我相信您已经知道了,但是您必须调用 CPUID 来检查处理器是否支持 RdRand。