News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

test for RdSeed

Started by jack, May 03, 2021, 10:48:33 AM

Previous topic - Next topic

jack

my CPU is Intel i9-9900K, so why does the following test fail?

mov eax, 7
xor ecx, ecx
cpuid
bt ebx, 18
jnc .exit
rdseed rax
mov qword ptr [n], rax
.exit:

that's FreeBasic inline-asm, n is a 64-bit integer

hutch--

I am not much use to you here Jack, I did a lot of work on random generators some years ago and remember testing rdrand which was as slow as a wet week but I don't think my Haswell generation CPUs support rdseed.

jack

RdSeed seems to work OK if I remove the conditional jump, but why does the test fail?
is the information about testing for the availability of RdSeed wrong?

hutch--

Jack,

Try and isolate the CPUID code from the RDSEED code. Do the CPUID code in a separate proc and if it returns the right result, then run the RDSEED instruction.

PS : Guys, no miseries please.

hutch--

Because my Haswell era CPU does not support RDSEED, I can get RDRAND to work OK.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    LOCAL cnt :QWORD

    mov cnt, 50

  lp:
    rdrand rax
    conout str$(rax),lf
    sub cnt, 1
    jnz lp

    waitkey
    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

jack

thanks hutch
it seem that the information found here is wrong https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
if I compile and run this C++ code https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-160 it correctly tells me that rdseed is supported

GenuineIntel
Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
.....
RDRAND supported
RDSEED supported
.....

jack

I still would like to know why the asm code fails, see https://software.intel.com/content/www/us/en/develop/articles/intel-digital-random-number-generator-drng-software-implementation-guide.html

jack

I think that the test was right, it's just that RdSeed doesn't always succeed, when that happens the result is 0
case closed.

hutch--

Jack,

Here is a seed generator that is very hard to improve on. The action is in the following small snippet.

    cpuid                                       ; set all regs to 0
    rdtsc                                       ; date time counter
    pause                                       ; spinlock pause
    bswap rax                                   ; reverse byte order
    mov r11, rax                                ; store rax in r11

This is the form I used it in.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

NOSTACKFRAME

reseed proc

    mov rax, 100                                ; out of range number
    cpuid                                       ; set all regs to 0
    rdtsc                                       ; date time counter
    pause                                       ; spinlock pause
    bswap rax                                   ; reverse byte order
    mov r11, rax                                ; store rax in r11

    mov rcx, 10                                 ; loop count
  @@:
    rdtsc                                       ; date time counter
    pause                                       ; spinlock pause
    bswap rax                                   ; reverse byte order
    rol rax, 7                                  ; rotate left by prime
    xor r11, rax                                ; xor rax to r11
    rol r11, 5                                  ; rotate left by prime
    sub rcx, 1                                  ; decrement counter

    jnz @B
    mov rax, r11                                ; return the value in r11
    ret

reseed endp

STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

Greenhorn

Quote from: jack on May 04, 2021, 12:50:44 AM
I think that the test was right, it's just that RdSeed doesn't always succeed, when that happens the result is 0
case closed.

»Hardware modifies the CF flag to indicate whether the value returned in the destination register is
valid. If CF = 1, the value is valid. If CF = 0, the value is invalid and will be returned as zero. Software
must test the state of the CF flag prior to using the value returned in the destination register to
determine if the value is valid. If the returned value is invalid, software must execute the instruction
again. Software should implement a retry limit to ensure forward progress of code.«

Quotet from the AMD manuals.

Strange that it does not work.
Kole Feut un Nordenwind gift en krusen Büdel un en lütten Pint.

InfiniteLoop

It works perfectly:

#include <iostream>
#include <string>
#include <Windows.h>
extern "C" unsigned long long ASM_test();
int main()
{
std::cout << "ASM bit test. Does rdseed exist? = " << std::to_string((ASM_test() == -1)) << std::endl;
Sleep(120000);
return(0);
}



ASM_test proc
push rbx
mov eax, 7
xor ecx,ecx
xor edx,edx
xor ebx,ebx
cpuid
;bt ebx, 5 ;AVX2
bt ebx,18 ;RDSEED
;bt ebx, 16 ;AVX-512
jnc Done ;equal to zero
mov rax, -1
Done:
pop rbx
ret
ASM_test endp