gpt4 book ai didi

delphi - 将 ASM 指令 RDRand 转换为 Win64

转载 作者:行者123 更新时间:2023-12-04 00:50:58 31 4
gpt4 key购买 nike

我有这个函数(RDRand - 由 David Heffernan 编写)在 32 位中接缝工作正常,但在 64 位中失败:

function TryRdRand(out Value: Cardinal): Boolean;
{$IF defined(CPU64BITS)}
asm .noframe
{$else}
asm
{$ifend}
db $0f
db $c7
db $f1
jc @success
xor eax,eax
ret
@success:
mov [eax],ecx
mov eax,1
end;

函数的文档在这里:https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide

特别是它写的:

Essentially, developers invoke this instruction with a single operand:the destination register where the random value will be stored. Notethat this register must be a general purpose register, and the size ofthe register (16, 32, or 64 bits) will determine the size of therandom value returned.

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

我对 ASM 的了解很低,我错过了什么?

我也不太明白这条指令:

  ...
xor eax,eax
ret
...

它的具体作用是什么?

最佳答案

如果您想要一个执行完全相同的函数,那么我认为它看起来像这样:

function TryRdRand(out Value: Cardinal): Boolean;
asm
{$if defined(WIN64)}
.noframe
// rdrand eax
db $0f
db $c7
db $f0
jnc @fail
mov [rcx],eax
{$elseif defined(WIN32)}
// rdrand ecx
db $0f
db $c7
db $f1
jnc @fail
mov [eax],ecx
{$else}
{$Message Fatal 'TryRdRand not implemented for this platform'}
{$endif}
mov eax,1
ret
@fail:
xor eax,eax
end;

Peter Cordes提出的建议在 asm 中实现重试循环对我来说看起来很明智。我不会尝试在这里实现它,因为我认为它在某种程度上超出了您的问题范围。

此外,Peter 指出,在 x64 中,您可以读取带有 REX.W=1 前缀的 64 位随机值。看起来像这样:

function TryRdRand(out Value: NativeUInt): Boolean;
asm
{$if defined(WIN64)}
.noframe
// rdrand rax
db $48 // REX.W = 1
db $0f
db $c7
db $f0
jnc @fail
mov [rcx],rax
{$elseif defined(WIN32)}
// rdrand ecx
db $0f
db $c7
db $f1
jnc @fail
mov [eax],ecx
{$else}
{$Message Fatal 'TryRdRand not implemented for this platform'}
{$endif}
mov eax,1
ret
@fail:
xor eax,eax
end;

关于delphi - 将 ASM 指令 RDRand 转换为 Win64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66699335/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com