2012-08-10 69 views
1

喂,我正在学习的x86 FPU组装,我已经 有一个简单的问题,我无法找到答案:如何将ST(0)移动到EAX?

如何值从ST(0)(FPU的 堆栈的顶部),以EAX动?

也:
是此代码正确:

; multiply (dot) two vectors of 3 floats passed by pointers as arg 1 arg 2 
; passings are ok I think, but not sure if multiplies-adds are ok 

    push ebp          
    mov  ebp, esp         
    mov  eax, dword [ebp+8H]      
    mov  edx, dword [ebp+0CH]      

    fld  qword [eax]        
    fmul qword [edx]        
    fld  qword [eax+4H]       
    fmul qword [edx+4H]       
    fld  qword [eax+8H]       
    fmul qword [edx+8H]       
    faddp st1, st(0)        
    faddp st1, st(0)        
    fstp qword [ebp+10H]  ; here I vould prefer 'mov eax, st0' 

    pop  ebp         
    ret           
+5

你想在EAX或整数表示(转换)的fp数字的位表示? – Necrolis 2012-08-10 10:43:54

+0

我想也许我做了某种错误,我需要编写类似C的函数来返回一个浮点数 - 我错误地认为ret值是由eax决定的,但这是浮点数,所以也许我应该把它放在st0上 - (现在我意识到了)除了我的FPU点(float *,float *)计算好吗? – 2012-08-10 10:51:14

+0

是的,在通常的调用约定中,FP值在'ST(0)'或'XMM0'中返回。不要在'eax'中,因为那么调用者必须将其反弹回'ST(0)'或'XMM0'来使用它。 – 2017-11-11 16:31:30

回答

5

为什么你应该没有真正的理由。请记住,EAX只是一个32位寄存器,而所有FPU寄存器的宽度都是80位,因为默认情况下,FPU在80位浮点数上进行计算。因此,将数据从FPU寄存器移至通用寄存器将导致数据丢失。如果你真的想这样做类似的东西,试试这个(假设你已经有了一些可用的堆栈空间):

sub esp, 4   ; or use space you already reserved 
fstp dword [esp] 
mov eax, [esp]  ; or better, pop eax 
add esp, 4 

该指令序列将当前舍入浮在FPU堆栈的顶部到32然后将其写入临时堆栈位置,将float(二进制32)位模式加载到EAX中,并清理已用堆栈空间。


这几乎从来都不是你想要的。 标准调用约定返回st(0)中的float/double/long double值,因此C编译器会预期double foo()函数会离开该值。 (或者具有SSE/SSE2的xmm0)。

你只需要这个,如果你想对FP位模式进行整数操作/测试。 (即,实现类似于C的类型双引号,如memcpy,从floatuint32_t)。例如用于Quake源代码中的famous but now mostly obsolete fast approximate inverse-sqrtf magic-number hack

+0

好吧,TNX的方式,不知道有没有这样的指示(这可能有点伤心,不得不使用RAM作为中间)但在这样的例程中,我已经测试过,我可以把结果放在堆栈顶部 - 它没问题 – 2012-08-10 13:02:58

+1

最后2条指令可以用'pop eax'替换。这对现代CPU来说至少有效。当然,通常你只需要在函数的开始处保留一些堆栈空间,然后将它们存储到/从中重新加载,而不是在循环中弄乱堆栈指针。 – 2017-11-11 16:27:47

3

没有的x87指令以移动浮动FPU寄存器和CPU寄存器之间点值。

您必须使用内存作为中间值。

+0

好的,你还可以说明我的点(float *,float *)过程是否可以吗? – 2012-08-10 10:56:37

+1

那么,如果你使用双打(qword =四字= 4 * 2字节= 8字节),你的偏移不能是4.你应该能够很容易地测试/调试你的代码。 – 2012-08-10 11:06:14