生成一个随机的 32 位数字存储在 64 位寄存器中

Generate a random 32-bit number to store in a 64-bit register

我想生成一个随机的 32 位数字。我为此使用 rdrand。但是,我遇到了一些问题。由于数字不能超过 32 位,所以我做的是 rdrand eax。问题出在这里:

有谁知道我的思维过程出了什么问题?我很想知道。 (注意:我在 macOS 上使用 Clang 进行组装。)

    .global _main
    .text

# how to generate a 32-bit random number that is in rax?
_main:
    xor rax, rax  # clear the top half of the eax-rax register pair
    rdrand eax  # a 32-bit number in rax

    cmp rax, 2147483647
    jle smaller_than_32  # rax <= MAX_32_BIT
    xor rdi, rdi
    jmp end
    smaller_than_32:
        mov rdi, 1
    end:
        mov rax, 0x2000001
        syscall

2147483647,或等效地,0x7FFFFFFF,是最大的 signed 32 位数字。 rdrand eax可以在eax中放入从0x000000000xFFFFFFFF的任何值。对于如何处理此问题,您有几种选择:

  1. 4294967295比较,或等价于0xFFFFFFFF,最大无符号 32位数字,而不是。
  2. cmp eax, 2147483647 而不是 cmp rax, 2147483647。由于 jle 对比较有符号整数的结果进行操作,这将导致您现在看到的 21474836484294967295 被解释为 -2147483648-1.
  3. 不是让 rax 的高 32 位始终为零,而是让它们匹配 eax 的符号位(这被称为 符号扩展).您可以通过在 rdrand eax 之后立即执行 movsx rax, eax 来做到这一点。这将导致 rax 保持 -21474836482147483647 之间的值,而不是 04294967295 之间的值。

如您所料,任何这些更改都会导致您的条件跳转始终被采用。如果您希望 rax 最终介于 04294967295 之间,请选择选项 1 或 2。如果您希望 rax 最终介于 -2147483648 之间和 2147483647,然后选择选项 3。