【问题标题】:MMX Instructions and the x87 FPU Tag WordMMX 指令和 x87 FPU 标签字
【发布时间】:2017-06-24 16:51:35
【问题描述】:
section .data
    qVar1: dq 1


section .bss
    var28: resb  28


section .text
    _main:

        ; Use an MMX instruction

            movq mm0, [qVar1] ; Move quadword from r/m64 to mm.

        ; Read Tag Word

            fstenv [var28]
            mov    ax, [var28 + 8] ; move the Tag Word to ax

此时ax0101 0101 0101 0110

但来自英特尔手册,9.5.1 MMX 指令和 x87 FPU 标记字部分,我引用:

在每个 MMX 指令之后,整个 x87 FPU 标签字都设置为有效 (00B)。

那么为什么ax 不是全零呢?

【问题讨论】:

    标签: assembly x86 fpu x87 mmx


    【解决方案1】:

    你引用的部分继续说:

    第 12 章,“英特尔® MMX™ 技术系统编程”,在英特尔® 64 和 IA-32 架构软件中 开发人员手册第 3A 卷提供了关于 x87 FPU 和 MMX 指令对 x87 FPU 标记字的影响的附加信息

    事实上,第三本手册的第 12.2 节阐明了:

    当MMX指令将值写入MMX寄存器时,同时对应的浮点寄存器的位64到79被设置为全1。

    指令movq mm0, [qVar1] 然后将寄存器R0 设置为0xffff_00000000_00000000,这是从80387 开始的无效double extended precision 浮点值(以前是正无穷大)。
    这在以后很重要。

    fstenv 指令保存实际的标签字,而是解释寄存器和实际的标签字来计算将存储在内存中的标签字。
    然后将所有寄存器的标记字寄存器重置为空。

    fstenv对x87 FPU标签字的影响是:

    标签和寄存器值被读取并 解释;然后所有标签都设置为 11B。

    而存储在内存中的x87 FPU标签字的图像是:

    标签根据实际设置 浮点寄存器中的值; 也就是说,空寄存器标记为 11B 有效寄存器标记为 00B (非零)、01B(零)或 10B(特殊)。

    如果您在任何 XMM 代码之前使用 emms,则标签将全部为 11b(空)。
    只要movq mm0, [qVar1] 被执行,所有标签都会设置为 00b(有效)。
    fstenv被执行时,寄存器被标记为非空并且它们的内容被分析:所有的寄存器R1-R7看起来都是零,而R0,如前所见,在内存中存储的图像中包含一个特殊的值和它的标签因此是 10b(特殊)。

    第二本手册中fstenv 的条目确实具有欺骗性,其伪代码写为

    操作
    DEST[FPUControlWord] ← FPUControlWord;
    DEST[FPUStatusWord] ← FPUStatusWord;
    DEST[FPUTagWord] ← FPUTagWord;
    DEST[FPUDataPointer] ← FPUDataPointer;
    DEST[FPUInstructionPointer] ← FPUInstructionPointer;
    DEST[FPULastInstructionOpcode] ← FPULastInstructionOpcode;

    这根本不是真的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多