x86汇编中的浮点

时间:2012-02-09 06:02:18

标签: assembly x86 floating-point

我目前正在尝试将平均值作为浮点数,四舍五入到最接近的.001

对浮点指令这么新,这就是我迄今为止所做的阅读和搜索。

总和:保存值为90的DWORD( acc 项目数之和)

acc :包含值7(项目数)

的DWORD

res :一个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范围)

2 个答案:

答案 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个项目求和然后除以项目数来计算平均值。

第二件事是您使用的是整数,而不是浮点值:fIldfIdivfIst指令的工作原理是使用整数,而不是浮点数值。如果使用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