Hullo,我正在学习x86 FPU程序集,我有 有一个简单的问题,我找不到答案:
如何从 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
答案 0 :(得分: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
(binary32)位模式加载到{{1清理用过的堆栈空间。
这几乎不是你想要的。 标准调用约定在EAX
中返回float / double / long double值,因此C编译器期望st(0)
函数保留该值。 (或double foo()
与SSE / SSE2)。
如果要对FP位模式进行整数操作/测试,则只需要这个。 (即从xmm0
到memcpy
实现类似float
的C中的类型双关语。例如对于Quake源代码中使用的famous but now mostly obsolete fast approximate inverse-sqrtf
magic-number hack。
答案 1 :(得分:3)
没有x87指令可以在FPU寄存器和CPU寄存器之间移动浮点值。
你必须使用记忆作为中间人。