X86 cvtsd2si指令未正确截断?
我想使用x86_64汇编(macOS上的叮当声)生成一个从1到10的随机数。以下是我为实现这一目标所做的努力: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
rdrand
rdi
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之间的随机数。稍后,我想将其扩展到任何开始和停止范围。