【问题标题】:How to load the value stored in extended register(eax) into st0 of floating point stack?如何将存储在扩展寄存器(eax)中的值加载到浮点堆栈的st0中?
【发布时间】:2016-06-12 14:06:16
【问题描述】:

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

fld dword [eax]

当我使用上述指令时,我没有得到期望的传输变化,可能是因为括号符号与内存地址而不是内容有关。 不过,我不确定。

【问题讨论】:

  • EAX 是整数还是已经包含浮点值?

标签: assembly x86 nasm x87


【解决方案1】:

您尝试使用此指令加载 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 堆栈时将整数值转换为浮点值。

【讨论】:

  • FreeBSD 的 x86-64 用户空间 ABI 使用与 Linux 相同的红色区域。你说的还有其他没有的 BSD 吗?
【解决方案2】:

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)

相信这会有所帮助

【讨论】:

  • dword ptrMASM,OP 标记为 NASM,这将是 mov dwordfld dword,没有 ptr 令牌。跨度>
  • 静态存储位置对于通用用途来说是一个糟糕的选择。更好:保留一些堆栈空间并使用[esp](或[ebp - something],如果您制作了堆栈框架)。或者push eax,就像迈克尔建议的那样。
【解决方案3】:
  fld     dword ptr [eax]

此代码运行良好! 但是 eax 必须指向有效的 32 位实数! 如果您使用的是 64 位真实版本,请使用:

  fld     qword ptr [eax]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2016-12-04
    相关资源
    最近更新 更多