gcc 如何使用RDRAND内部函数?

eit6fx6z  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(159)

我在看H.J. Lu的PATCH: Update x86 rdrand intrinsics。我不知道我是否应该使用_rdrand_u64_rdrand64_step,或者是否有其他函数。似乎没有为它们编写测试用例。
似乎也缺少手册页(来自Ubuntu 14,GCC 4.8.4):

$ man -k rdrand
rdrand: nothing appropriate.

如何使用RDRAND内部函数生成一个32字节的块?
一个相关的问题是RDRAND and RDSEED intrinsics GCC and Intel C++。但是它没有告诉我如何使用它们,或者如何生成一个块。

roejwanj

roejwanj1#

如果你看一下<immintrin.h>(我的在'/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及其它编译器兼容。
_rdrand64_step将用随机位填充指针传递的64位参数并返回错误代码。32位和16位版本同上
更新
“这些内部函数生成16/32/64位宽随机整数的随机数。生成的随机值被写入给定的内存位置,并返回成功状态:如果硬件返回有效的随机值,则为“1”,否则为“0”。
https://software.intel.com/en-us/node/523864
更新
根据@vy32的要求,这对我来说是有效的。嗯,我的系统gt更新后,原来的答案,所以现在它是Ubuntu 20.04.1,x64,GCC v9.3,编译标志

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);
}

关于CF标志和“忽略这是一个常见的实现错误,在测试中不会出现,但在加载下运行DRNG时会出现”,我相信这就是内置所做的。如果注解掉printf并使用-S标志编译为汇编程序,代码将看起来像,

xorl    %eax, %eax
rdrand  %rax
movl    $1, %edx
...    
cmovc   %edx, %eax

这意味着%eax被置零,%edx被设置为1,然后通过cmovc%edx可能被设置为0,如果CF被提升,这个值从函数返回。
因此,我相信内置程序已经以正确的方式处理进位标志,用户只需按照手册中的描述检查_rdrandXX_step(ull*)的输出。
注意文件immintrin.h是定义处理器内部函数的所有类型的头文件的集合。包含RDRAND内部函数的 current 头文件是x86gprintrin.h,您 * 不应该 * 包含它。

相关问题