如何将存储在扩展寄存器(eax)中的值加载到浮点堆栈的st0中?

时间:2016-06-12 14:06:17

标签: assembly x86 nasm x87

如何将存储在扩展寄存器(eax)中的值加载到浮点堆栈的st0中?

fld dword [eax]

当我使用上述指令时,我没有得到所需的转移更改,因为括号标记与内存地址有关,而与内容无关。 虽然,我不确定。

3 个答案:

答案 0 :(得分:4)

您尝试使用此指令加载 EAX 不会执行您认为的操作:

fld dword [eax]

这将从 EAX 指向的内存位置加载32位浮点值(这是indirect addressing)。我相信您想要使用 EAX 的值加载 ST(0)

如果你必须使用 x87 FPU 指令而不是 SSE ,那么我建议将值存储在 EAX 中临时在堆栈而不是像@ quasar66建议的固定内存位置。将它放在堆栈上也可以使您的代码变为re-entrant

如果代码在已经为临时工具分配空间的函数中,只需增加堆栈分配以允许将另一个32位值存储到它并将 EAX 移动到该堆栈位置然后使用fld从那里加载。

最终,32位代码可能被编写为具有类似效果

push EAX           ; Store EAX to top of stack
fld dword [esp]    ; Load 32-bit DWORD value at top of stack to ST(0)    
POP EAX            ; Restore stack, alternatively could have used add esp, 4         
; do other floating point work here   

在遵循System V 64位ABI(不适用于64位Windows)的64位操作系统上,您可以将数据直接移动到堆栈red zone,而无需担心它被破坏了。这样的64位代码看起来像这样:

mov [rsp-4], eax   ; Temporarily place EAX in the stack's red zone beneath current RSP
fld dword[rsp-4]   ; Load it into ST0
; do other stuff here
                   ; No need for stack cleanup

请勿在32位代码中尝试此操作,因为异步事件(信号等)可能会在mov之后和fld之前破坏堆栈上的值。

您的问题中没有明确的是 EAX 中的值是否为整数,或者它是否恰好是32位浮点值。如果它是一个整数,您必须在我的答案中用FLD替换FILD,以便在加载到FPU堆栈时将整数值转换为浮点值。

答案 1 :(得分:1)

FLD指令只能从内存中读取,因此您需要将EAX的值保存到内存位置,然后进行内存上传。

a_memory_place    dd     ?
.
mov dword ptr [a_memory_place],eax
fld dword ptr [a_memory_place]      ; loads a 32 bit data into ST(0)

相信这有助于

答案 2 :(得分:0)

  fld     dword ptr [eax]

此代码效果很好! 但 eax 必须指向有效的32位真实! 如果您使用64位实时,请使用:

  fld     qword ptr [eax]