如何将ST(0)移至EAX? [英] How to move ST(0) to 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
那样从float
到uint32_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屋!