如何将ST(0)移至EAX? [英] How to move ST(0) to EAX?

查看:172
本文介绍了如何将ST(0)移至EAX?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hullo,我正在学习x86 FPU组装,并且我有 有一个简单的问题,我找不到答案:

Hullo, I am learning x86 FPU assembly, and I have got a simple question I cannot find answer for:

如何从 ST(0) (FPU的顶部)转移价值 堆栈)到 EAX 吗?

How to move value from ST(0) ( top of the FPU stack ) to EAX ?

还:
此代码正确吗:

also:
is this code correct:

; 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                                           

推荐答案

没有真正的理由.请记住,EAX只是一个32位寄存器,而所有FPU寄存器的宽度均为80位,因为默认情况下FPU会对80位浮点数进行计算.因此,将数据从FPU寄存器移至通用寄存器将导致数据丢失.如果您确实想执行类似的操作,请尝试以下操作(假设您有一些可用的堆栈空间):

There is no real reason why you should. Remember that EAX is only a 32-bit register, while all the FPU registers are 80 bits in width, because the FPU does calculations on 80-bit floats by default. Therefore, moving data from the FPU register to a general purpose register will cause data loss. If you really want to do something like that, try this (assuming that you've got some stack space available) :

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(binary32)位模式加载到EAX中,然后清理已使用的堆栈空间.

This instruction sequence will round the float currently on the top of the FPU stack to a 32-bit one, then write it to a temporary stack location, load the float (binary32) bit pattern into EAX, and clean up the used stack space.

这几乎永远不是您想要的. 标准调用约定在st(0) 中返回float/double/long double值,因此C编译器将期望double foo()函数保留该值. (或xmm0与SSE/SSE2).

This is almost never what you want. The standard calling conventions return float / double / long double values in st(0), so that's where a C compiler will expect a double foo() function to leave the value. (Or xmm0 with SSE/SSE2).

仅当您要对FP位模式进行整数操作/测试时才需要此选项. (即,在C中像memcpy那样从floatuint32_t实现类型修饰).例如适用于著名但现在已经过时的快速近似逆-sqrtf Quake源代码中使用的magic-number hack .

You only need this if you want to do integer manipulation / tests on FP bit-patterns. (i.e. to implement type-punning in C like memcpy from a float to uint32_t). e.g. for the famous but now mostly obsolete fast approximate inverse-sqrtf magic-number hack used in Quake source code.

这篇关于如何将ST(0)移至EAX?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆