Использование кода операции Intel RdRand в Delphi 6/7

Есть ли способ использовать код операции Intel RdRand в более старых версиях Delphi, таких как 6 или 7?

Может быть, используя

asm db $... end;

или что-то? Как мне сохранить число в переменной?

Скорость очень важна. Я не могу использовать внешнюю библиотеку для этого.

1 ответ

Решение

Я не могу проверить это, так как мой процессор не поддерживает 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;

Опять же, я не могу это проверить, но я надеюсь, что это поможет вам в пути. ModR/M 0xf1 помещает выходное значение в ecx, которое я затем копирую в [eax], если операция прошла успешно.

Приведенная выше документация продолжает:

Рекомендуется, чтобы приложения пытались выполнить 10 повторных попыток в замкнутом цикле в маловероятном случае, когда инструкция RDRAND не возвращает случайное число. Это число основано на аргументе биномиальной вероятности: с учетом проектных полей DRNG шансы десяти отказов подряд астрономически невелики и фактически будут указывать на большую проблему с процессором.

Вы можете легко реализовать эту политику повторных попыток поверх функции выше.

Наконец, я уверен, что вы знаете, но вы должны сделать вызов CPUID, чтобы убедиться, что процессор поддерживает RdRand.

Другие вопросы по тегам