将ASM指令RDRand转换为Win64

洛基

我有此功能(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/zh-cn/articles/intel-digital-random-number-generator-drng-software-implementation-guide

特别是这样写:

本质上,开发人员使用单个操作数调用该指令:将存储随机值的目标寄存器。请注意,该寄存器必须是通用寄存器,并且寄存器的大小(16位,32位或64位)将确定返回的随机值的大小。

调用RDRAND指令后,调用方必须检查进位标志(CF),以确定在执行RDRAND指令时是否可以使用随机值。如表3所示,值1表示一个随机值可用,并将其放在调用中提供的目标寄存器中。值为0表示随机值不可用。在当前架构中,由于这种情况的副作用,目标寄存器也将被清零。

我对ASM的了解很低,我想念什么?

我也不太明白这条指令:

  ...
  xor  eax,eax
  ret
  ...

它到底是做什么的?

大卫·赫弗南(David Heffernan)

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

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中实现重试循环的建议对我来说似乎很明智。我不会在这里尝试实现这一点,因为我认为这在您的问题范围之外。

另外,彼得指出,在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;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将插件转换为指令

来自分类Dev

将jQuery插件转换为指令Angular

来自分类Dev

将Fancybox插件转换为Angular指令

来自分类Dev

将angularjs指令转换为angular 10

来自分类Dev

将JQuery插件转换为AngularJS指令?

来自分类Dev

通过指令将数字转换为货币

来自分类Dev

将指令序列转换为图表

来自分类Dev

在Delphi中,编译器指令WIN32和CPUX86,WIN64和CPUX64是否可以互换?

来自分类Dev

WiX Heat.exe Win64组件-Win64 =“ yes”

来自分类Dev

#ifdef WIN32 #elif WIN64 #endif

来自分类Dev

将AT&T语法转换为Intel语法(ASM)

来自分类Dev

将图像转换为base64

来自分类Dev

将R图像转换为Base 64

来自分类Dev

将WAV转换为base64

来自分类Dev

将JInputStream转换为Base64

来自分类Dev

将WAV转换为base64

来自分类Dev

将int转换为float会导致非法指令

来自分类Dev

将Angular 1.x指令转换为Angular 2

来自分类Dev

将jQuery UI滑块小部件转换为AngularJS指令

来自分类Dev

药剂宏指令:将原子转换为变量

来自分类Dev

如何将MIPS指令转换为机器代码?

来自分类Dev

通过角度指令将布尔值转换为是/否

来自分类Dev

将JQuery树插件转换为Angularjs指令

来自分类Dev

如何将Shellcode转换为可读的汇编代码/指令?

来自分类Dev

将控制器代码转换为可重用指令

来自分类Dev

如何将MIPS指令转换为机器代码?

来自分类Dev

将int转换为float会导致非法指令

来自分类Dev

将orderBy过滤器转换为指令

来自分类Dev

将Angular 1.x指令转换为Angular 2