x87 FPOP和FCOM指令 - 这些如何工作?

use*_*747 5 c x86 assembly x87

我的任务是在混合C/ASM中编写一个简单的应用程序,它必须使用数学协处理器.

有一个函数柱面(float x,float y,float z),如果给定的点位于柱面内,则返回1(柱面的底边为x = 0,y = 0,半径= 5,高度= 10),如果不是,则为0.

所以,看起来很简单.检查z是否在<0,10>范围内,然后检查x ^ 2 + y ^ 2 <25.

但是我对x87的了解是零.

这就是我写的一切.

_cylinder PROC

push ebp
mov ebp, esp
sub esp,8 ; I can't use .data in the application, so I reserve some space on the stack for numbers 10 and 25
mov [esp],10
mov [esp+4],25

finit
fldz
fld [ebp+8]

    ;here i get stuck 

add esp, 8
pop ebp
_cylinder ENDP
Run Code Online (Sandbox Code Playgroud)

所以我卡住了.所以,我试着找到我可以在应用程序中使用的指令.在那里我卡住了,因为我在网上找到的每个教程/指令列表写得非常糟糕,我几乎无法理解任何东西.

问题是,当我从数学协处理器弹出一些东西时会发生什么?我在哪里可以找到弹出值?它如何从80位值转换为32位值(当然如果有)另一个问题是,FCOM(用于pop变体的FCOMP)如何工作?它比较什么(st0到st1或st1到st0?),在哪里可以看到值是小/等于/更大?

谢谢你的帮助!

Jer*_*fin 5

浮点比较是一种痛苦.你可以在FPU上进行比较,但在你可以做任何事情之前,你必须将浮点状态字转移到CPU,测试你关心的标志,然后根据它做出反应.

例如,您对z> = 0.0的初始比较看起来像这样:

fldz
fcomp z
fnstsw ax
test ah, 041h; I *think* I've got the right flags there...
jp good
Run Code Online (Sandbox Code Playgroud)

  • 嗯,不应该是`测试啊,......?[参考文献](http://webster.cs.ucr.edu/AoA/Windows/HTML/RealArithmetic.html#1000117).就个人而言,我发现使用[`FCOMI`](http://stackoverflow.com/questions/7057501/x86-assembler-floating-point-compare/7057771#7057771)比使用状态字的位掩码更容易,它只是可用的虽然在P6 +上. (4认同)
  • @ user786653:oops - 是的,应该是啊,不是斧头.我很抱歉.是的,FCOMI很好,但到P6出现的时候,我的编写代码差不多.如果我是为更新的处理器编写的,我可能会使用SSE代替. (3认同)
  • 我同意,如果我*在*x86汇编程序中写它.看起来就像使用x87设置了OP,所以我想我会在那里完成它.我似乎也很难回忆起`sahf` + unsigned tests(与`fcomi`一样). (2认同)
  • @Brian:我相信*在这种情况下你可以使用FNSTSW. (2认同)