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

时间:2015-02-16 09:38:07

标签: delphi assembly random opcode rdrand

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

也许正在使用

ASM   db $ ... 端;

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

速度非常重要。我无法使用外部库。

1 个答案:

答案 0 :(得分:2)

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

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

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

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

  

在调用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]。

以上链接的文档继续说:

  

建议应用程序在RDRAND指令不返回随机数的情况下,在紧密循环中尝试重试10次。这个数字基于二项式概率论证:给定DRNG的设计余量,连续十次失败的几率是天文数字小,实际上是一个更大的CPU问题的指示。

您可以在上面的函数之上轻松实现此重试策略。

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