I am trying to understand the x86 assembly function used in OpenSSL to get random bytes using the CPU's RDRAND instruction. Here is the function body:
OPENSSL_ia32_rdrand:
mov $8,%ecx
.Loop_rdrand:
rdrand %rax
jc .Lbreak_rdrand
loop .Loop_rdrand
.Lbreak_rdrand:
cmp $0,%rax
cmove %rcx,%rax
ret
I can't figure out the purpose the the cmp and cmove instructions. I am not an x86 assembly programmer, but from what I can tell from the references that I've looked at, my understanding of what it's doing is:
10 load retry counter to ecx
20 get random number into rax
30 if successful (carry flag set) goto 50
40 decrement counter and goto 20 if not zero
50 check if rax is zero
60 if it is, move rcx to rax
70 return
So, rax can only be 0 if rdrand failed (carry flag is clear), and the cmp instruction can only be reached if either 1) rdrand succeeded (carry set) and put a non-zero number in rax, or 2) the retry counter in ecx has been decremented to 0. In case 1, the cmp fails and cmove does not execute the move. In case 2, rcx contains 0 and cmove moves 0 to 0. Either way the cmove is a no-op.
Am I misunderstanding what one or more of the assembly instructions do?