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

标签 assembly x86 nasm x87

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

fld dword [eax]

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

最佳答案

您尝试使用此指令加载 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 位操作系统上(不适用于 64 位 Windows),您可以将数据直接移动到堆栈的 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 位浮点值。如果它是一个整数,你必须替换 FLDFILD在我的回答中,当加载到 FPU 堆栈时将整数值转换为浮点值。

关于assembly - 如何将存储在扩展寄存器(eax)中的值加载到浮点堆栈的st0中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37775144/

相关文章:

c - 汇编输出+有关堆栈的问题

c - SSE2 指令将一个 8x16 寄存器转换为两个具有偶数和奇数索引元素的 4x32 寄存器

assembly - Hook Int 09h 中断

assembly - 无法在 Windows 7 中运行 nasm 生成的可执行文件

assembly - 为什么我的堆栈指针仅以16的倍数递增?

assembly - 如何在裸机 16 位 x86 程序集中休眠?

c - ASM 调用约定

assembly - BIOS 中断如何与保留的硬件中断冲突?

x86 - Spectre (v2) 的内部工作原理

linux - NASM:如何使用英特尔 64 位程序集创建/处理基本 bmp 文件?