我正在尝试用汇率点在汇编中实现一个等式,它给了我错误的答案。
我把它放在一个caculater中它给了我433.0127018 ...并且我的代码我得到了0.0193269641235答案甚至没有接近正确但我无法找出它为什么给错了aswer。
式:
initX=sin((degree+ (i∗dStep)) ∗pi/180) ∗ scale
变量:
degree dd 0
dStep dq 120.0
scale dq 500.0
pi dq 3.14159265358979
oneEighty dq 180.0
initX dq 0.0
tmp dq 0.0
tmptmpdegree dq 0.0
代码:
; initX=sin((degree+(i*dstep))*pi/180)*scale
movsxd r10,dword[degree]
cvtsi2sd xmm0,r10
movsd qword[tmpdegree],xmm0
movsd xmm1,qword[pi]
divss xmm1,dword[oneEighty]
movsd qword[tmp],xmm1
movsd xmm0,qword[tmpdegree]
addsd xmm0,qword[dStep]
mulsd xmm0,qword[tmp]
call sin
mulsd xmm0,qword[scale]
movsd qword[initX],xmm0
答案 0 :(得分:2)
divss
is single-precision,你在双精度数据上使用它。您甚至写了dword [oneEighty]
,即使您在该标签上放置了dq
浮点数。
因此,您将double
的尾数的低32位视为float
。
就像Jester所说,调试器会告诉你xmm1
中的值没有改变到你在该指令之后所期望的值。
有关详情,请参阅x86代码维基。
更好的方法是在汇编时将两个常数组合在一起,只存储pi/180.0
,这样你根本不需要分割。请记住,你是编译器。如果您希望您的代码不会吮吸,您必须找到自己简化代码的方法。
此外,这是毫无意义的:
movsd qword[tmp], xmm1
...
mulsd xmm0, qword[tmp]
这些说明之间没有任何内容会破坏xmm1,所以你应该将值保留在xmm1中。
tmpdegree
相同。当你准备好时,你应该cvtsi2sd xmm0, [degree]
。
您还应该将degree
作为arg放在注册表中,而不是全局。而且你的常量与变量混合在一起。将常量放在.rodata
部分。