RosettaCodeData/Task/Random-number-generator--device-/Phix/random-number-generator--device--1.phix
2018-08-17 15:15:24 +01:00

55 lines
1.2 KiB
Text

integer res -- 1=failure, 0=success
atom rint = 0 -- random 32-bit int
#ilASM{
mov eax,1
cpuid
bt ecx,30
mov edi,1 -- exit code: failure
jnc :exit
-- rdrand sets CF=0 if no random number
-- was available. Intel documentation
-- recommends 10 retries in a tight loop
mov ecx,11
::loop1
sub ecx, 1
jz :exit -- exit code is set already
rdrand eax
-- (the above generates exception #C000001D if not supported)
-- rdtsc
jnc :loop1
lea edi,[rint]
call :%pStoreMint
xor edi,edi
::exit
mov [res],edi
xor ebx,ebx -- important!
}
?{res,rint}
if res=0 then -- (success)
--
-- To convert a signed 32-bit int to an unsigned one:
--
-- method 1
-- atom urint1 = rint
-- if urint1<0 then urint1+=#100000000 end if
atom urint1 = rint+iff(rint<0?#100000000:0)
-- method 2
atom pMem = allocate(4)
poke4(pMem,rint)
atom urint2 = peek4u(pMem)
free(pMem)
-- method 3
atom urint3 = bytes_to_int(int_to_bytes(rint,4),signed:=false)
?{urint1,urint2,urint3}
end if