Gcc 如何使用RDRAND内部函数?

Gcc 如何使用RDRAND内部函数?,gcc,intrinsics,rdrand,Gcc,Intrinsics,Rdrand,我在看陆海杰的。我不知道我是否应该使用\u rdrand\u u64,\u rdrand64\u step,或者是否有其他功能。似乎没有为他们编写测试用例 似乎也缺少手册页(来自Ubuntu 14,GCC 4.8.4): 如何使用RDRANDintrinsic生成一个32字节的块 一个相关的问题是。但是它没有告诉我如何使用它们,或者如何生成一个块。如果你看一下(我的在`/usr/lib/gcc/x86_64-linux-gnu/4.9/include/',Ubuntu 15.04 64位),有

我在看陆海杰的。我不知道我是否应该使用
\u rdrand\u u64
\u rdrand64\u step
,或者是否有其他功能。似乎没有为他们编写测试用例

似乎也缺少手册页(来自Ubuntu 14,GCC 4.8.4):

如何使用
RDRAND
intrinsic生成一个32字节的块


一个相关的问题是。但是它没有告诉我如何使用它们,或者如何生成一个块。

如果你看一下
(我的在`/usr/lib/gcc/x86_64-linux-gnu/4.9/include/',Ubuntu 15.04 64位),有一些兼容的(与MSVC、Intel CC)函数定义,它们将数据传递回gcc内置

extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_rdrand64_step (unsigned long long *__P)
{
     return __builtin_ia32_rdrand64_step (__P);
}
用于64位参数,另外两个用于16位和32位参数

_rdrand16_step (unsigned short *__P)
_rdrand32_step (unsigned int *__P)
您应该使用这些代码,这样您的代码就可以与MSVC、英特尔CC和其他编译器兼容

\u rdrand64\u步骤
将用随机位填充指针传递的64位参数并返回错误代码。32位和16位版本同上

更新

这些内部函数生成16/32/64位宽随机整数的随机数。生成的随机值将写入给定的内存位置,并返回成功状态:如果硬件返回有效的随机值,则返回“1”,否则返回“0”

更新

根据@vy32请求,这对我有效。好的,我的系统gt更新了原始答案,所以现在它是Ubuntu 20.04.1,x64,GCC v9.3,编译标志

gcc -m64 -mrdrnd -O3 a.c
代码

这意味着
%eax
为零,
%edx
设置为1,然后通过
cmovc
%edx
如果引发CF,则可能设置为0。这个值是从函数返回的


因此,我相信内置软件已经以正确的方式处理进位标志,用户只需检查手册中描述的
\rdrandXX\u步骤(ull*)
的输出。

@Filip-是的,BullRun由于斯诺登泄漏(等人)而受到了很多负面批评。在本例中,我使用了一个自定义的随机数生成器,它提取然后扩展熵。有多个来源,因此NSA后门不会导致灾难性的发电机故障。返回值是多少?我们如何知道函数成功还是失败?GCC把这搞得一团糟。他们使用的是令人沮丧的。@vy32您到底想要什么?为什么需要carryflag wrt随机数?@SeverinAppadeux您应该阅读英特尔应用程序说明。DRNG只能提供800MB/s的随机性,如果没有可用的随机性,它会清除CF。忽略这一点是一个常见的实现错误,它不会在测试中出现,但在load下运行DRNG时会出现。顺便说一句,您可以发布一个完整的工作示例吗?我无法使
\r和64\u步骤
在实际程序中工作。谢谢
gcc -m64 -mrdrnd -O3 a.c
#include <stdio.h>
#include <immintrin.h>

int main() {
    unsigned long long result = 0ULL;

    int rc = _rdrand64_step (&result);

    printf("%i %llu", rc, result);

    return (rc != 1);
}
xorl    %eax, %eax
rdrand  %rax
movl    $1, %edx
...    
cmovc   %edx, %eax