X86 cvtsd2si指令未正确截断?

X86 cvtsd2si指令未正确截断?,x86,floating-point,x86-64,sse,X86,Floating Point,X86 64,Sse,我想使用x86_64汇编(macOS上的叮当声)生成一个从1到10的随机数。以下是我为实现这一目标所做的努力: rdrand 将其除以32位最大值,这将得到一个从0到1的浮点值 乘以10 将其截断为整数,并将其存储在rdi 这是行不通的。LLDB跟踪显示,rdi包含9223372036854775808,这是非常意外的。我做错了什么 .global _main .text _main: rdrand rsi mov [storage + rip], rsi

我想使用x86_64汇编(macOS上的叮当声)生成一个从1到10的随机数。以下是我为实现这一目标所做的努力:

  • rdrand
  • 将其除以32位最大值,这将得到一个从0到1的浮点值
  • 乘以10
  • 将其截断为整数,并将其存储在
    rdi
  • 这是行不通的。LLDB跟踪显示,
    rdi
    包含9223372036854775808,这是非常意外的。我做错了什么

        .global _main
        .text
    _main:
        rdrand rsi
        mov [storage + rip], rsi
        movsd xmm0, qword ptr [storage + rip]
        divsd xmm0, qword ptr [MAX_32 + rip]  # ratio
        mov qword ptr [storage + rip], 10  # mul by 10
        mulsd xmm0, qword ptr [storage + rip]
    
        cvtsd2si rdi, xmm0  # why is rdi not reasonable?
    
        /*
        What I want to happen:
    
        1. I get a random number from 1 to MAX_32
        2. I divide that by MAX_32
        3. I multiply it by 10
        That means that rdi should contain a number from 1 to 10. But LLDB shows this:
    
        (lldb) register read rdi
            rdi = 0x8000000000000000
    
        0x8000000000000000 = 9223372036854775808, which is too big
    
        What is going wrong here?
        */
    
        mov rax, 0x2000001
        syscall
    
        .data
    storage:
        .quad 0
    MAX_32:
        .quad 2147483647
    

    cvtsd2si
    将舍入模式转换为最近模式(或任何默认舍入模式)<代码>cvttsd2si截断。显然,这不是你唯一的问题(因为它只是一个off-by-1),而是我对标题的期望。
    movsd xmm0,qword ptr[storage+rip]
    -为什么你要将一个随机的64位整数作为双精度位模式重新加载,而不是将整数转换成一个
    double
    ?大约一半的IEEE754二进制64(也称为双字节)位模式表示小于1.0的数字。此外,整数
    .quad 2147483647
    表示(作为
    双精度
    )一个非常小的次正常值,除尾数底部外,处处都是零。另外,
    rdrand rsi
    生成一个64位整数,您可能应该将其视为无符号整数。无论如何,
    9223372036854775808
    是不确定整数值(
    0x8000000…
    ),如手册所述,当实际整数值不适合目标时,您会得到该数值。从这里开始,您可以通过打印
    $xmm0.v2\u double
    或LLDB调用的任何东西来进行调试,以查看转换后的double值,并从中向后查找错误。只是想知道-这是一个浮点练习,还是您真的只是想得到1到10之间的随机数?有一些纯粹的整数算法更简单,偏差更小:丢弃任何值>=2^32以下10的最大倍数,然后取余数mod 10。@NateEldredge我实际上是想得到一个介于1和10之间的随机数。稍后,我想将其扩展到任何开始和停止范围。