1

6 や 7 などの古いバージョンの Delphi で Intel の 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] にコピーします。

上記のリンクされたドキュメントは、次のように続けています。

RDRAND 命令が乱数を返さないという万一の事態に備えて、アプリケーションはタイトなループで 10 回の再試行を試みることをお勧めします。この数値は、二項確率の議論に基づいています。DRNG の設計マージンを考えると、連続して 10 回失敗する可能性は天文学的に小さく、実際には CPU の問題が大きいことを示しています。

この再試行ポリシーは、上記の関数の上に簡単に実装できます。

最後に、お気付きだと思いますが、CPUID を呼び出して、プロセッサが RdRand をサポートしているかどうかを確認する必要があります。

于 2015-02-16T10:20:32.807 に答える