1

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

  • 我需要能够在 64 位寄存器中引用这个 32 位数字,因为我的代码库的其余部分使用 64 位寄存器。我想我可以rax用 axor自己清除,然后只用rdrand eax. 然后我可以看一下rax,一半最多是32位数字,另一半被清除。

  • 当我rax与最大 32 位数字大小2147483647进行比较时,我得到的结果非常不一致。有一半的时候,退出码是 1,这意味着实际上里面的数字rax小于 32 位。但另一半时间我得到 0。几乎就像结果eax并不总是小于或等于2147483647 ,考虑到文档所说的内容,这是出乎意料的。

有谁知道我的思维过程出了什么问题?我很想知道。(注意:我在 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
4

1 回答 1

4

2147483647,或等效地,0x7FFFFFFF是最大的有符号32 位数。rdrand eax可以将任何值从0x00000000to 0xFFFFFFFFin eax。对于如何处理这个问题,您有几个选择:

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

如您所料,任何这些更改都会导致您的条件跳转始终被执行。如果你想rax最终介于0和之间4294967295,请选择选项 1 或 2。如果你想rax最终介于-2147483648和之间2147483647,请选择选项 3。

于 2020-11-20T18:08:48.010 回答