我目前正在尝试将平均值作为浮点数,四舍五入到最接近的.001
对浮点指令这么新,这就是我迄今为止所做的阅读和搜索。
总和:保存值为90的DWORD( acc 项目数之和)
acc :包含值7(项目数)
的DWORDres :一个DWORD来回答。
最后,edx的值为0.这是为什么? 另外,我如何围绕浮点?
或者......有更好的方法吗?
我的主持人:
push dword ptr sum
fild dword ptr [esp]
push dword ptr acc
fild dword ptr [esp]
add esp,4
fdiv st(0), st(1)
sub esp,4
fstp dword ptr [esp]
pop eax
add esp,4
mov edx, eax
另外,我试过这个:
finit
fild sum
fidiv acc
frndint
fist res
mov eax, res
但是......结果是:2147483648(DWORD范围)
答案 0 :(得分:1)
你的代码中似乎有很多不需要的堆栈操作,但是,这里存在一个更加险恶的问题,将fp结果存储在DWORD
会截断它,所以没有任何意义除非你计划舍入到最接近的整数值(这是你的第二次尝试)。
因此,我将以第二次尝试为例:
PUSH ECX
FILD [ESP]
PUSH EDX
FILD [ESP]
FDIV
FRNDINT
ADD ESP,4
FISTP DWORD PTR [ESP]
POP EAX
RETN
此函数假设ECX
中的值,EDX
中的计数,并返回EAX
中的舍入平均值。在这里你可以改变它来使用你的全局变量,或者使用你的全局变量将它作为一个函数来调用
答案 1 :(得分:1)
我不确定我是否理解你的问题,但至少第二位代码似乎有效。它是否能满足您的需求是另一个问题。它这样做:
finit
fild sum ;//ST(0) = 90
fidiv acc ;//ST(0) = ST(0) / acc = 90 / 7 = 12.857..
frndint ;//ST(0) = 13
fist res ;//RES= ST(0) = 13
mov eax, res ;//EAX = RES = 13
换句话说,你正在计算回合(90/7)= 13.
现在,这是一个简单的划分,而不是平均。您显然可以通过对N个项目求和然后除以项目数来计算平均值。
第二件事是您使用的是整数,而不是浮点值:fIld
,fIdiv
和fIst
指令的工作原理是使用整数,而不是浮点数值。如果使用fIst
而不是fst/fstp
将FPU中的值存储到内存中,则内存中的值将是整数值,而不是浮点值。这是你想要的吗?
要将FPU中的浮点值存储到[eax]
指向的内存,可以使用
fstp dword ptr [eax] ;// Store Single-Precision Floating point value (4 bytes)
fstp qword ptr [eax] ;// Store Double-Precision Floating point value (8 bytes)
fstp tbyte ptr [eax] ;// Store Long Double-Precision Floating point value (10 bytes)
单人和双人商店(但不是tbyte ptr
)也适用于fst
而不是fstp
。