Использование кода операции 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.