我试图了解 OpenSSL 中使用的 x86 汇编函数,以使用 CPU 的 RDRAND 指令获取随机字节。这是函数体:

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

我无法弄清楚 cmp 和 cmove 指令的目的。我不是 x86 汇编程序员,但从我看过的引用资料中可以看出,我对它在做什么的理解是:
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

因此,如果 rdrand 失败(进位标志清零),rax 只能为 0,并且只有在 1)rdrand 成功(进位设置)并在 rax 中放入一个非零数字,或 2)重试时,才能到达 cmp 指令ecx 中的 counter 已递减为 0。在情况 1 中,cmp 失败且 cmove 不执行移动。在情况 2 中,rcx 包含 0,cmove 将 0 移动到 0。无论哪种方式,cmove 都是空操作。

我是否误解了一个或多个组装说明的作用?

最佳答案

你有一个小小的误会。

您说对了主要部分,有 8 次尝试使用 RDRAND 检索随机数,但如果 CMOVE 返回 0 作为随机数,则 NOP 不一定是 RDRAND。在这种情况下,该函数将 RCX(循环计数)的值作为“随机数”返回。简而言之,此函数仅在没有可用随机数时返回 0 - 否则它将返回来自 RDRAND 的真实随机数或从 RDRAND 收到 0 的迭代数。

关于assembly - OPENSSL_ia32_rdrand cmp/cmove 指令,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23360694/

10-11 17:43