MMX 指令和 x87 FPU 标记字
MMX Instructions and the x87 FPU Tag Word
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
此时ax
是0101 0101 0101 0110
但是从 Intel 手册,第 9.5.1 MMX 指令和 x87 FPU 标记字 部分,我引用:
After each MMX instruction, the entire x87 FPU tag word is set to valid (00B).
那么为什么 ax
不全是零?
您引用的部分继续说:
Chapter 12, “Intel® MMX™ Technology System Programming,” in the Intel® 64 and IA-32 Architectures Software
Developer’s Manual, Volume 3A, provides additional information about the effects of x87 FPU and MMX instructions on the x87 FPU tag word.
实际上第三本手册12.2节阐明:
When an MMX instruction writes a value into an MMX register, at the same time, bits 64 through 79 of the corresponding floating-point register are set to all 1s.
指令movq mm0, [qVar1]
然后将寄存器R0
设置为0xffff_00000000_00000000这是一个无效的double extended precision从80387开始的浮点值(之前是正无穷大) .
这在以后很重要。
fstenv
指令不保存实际的标记字,而是解释寄存器和实际的标记字来计算将存储的标记字在记忆中。
然后将所有寄存器的标记字寄存器重置为空。
fstenv
对x87 FPU标签字的影响是:
Tags and register values are read and
interpreted; then all tags are set to 11B.
而内存中存储的x87 FPU tag word的图像为:
Tags are set according to the actual
values in the floating-point registers;
that is, empty registers are marked 11B
and valid registers are marked 00B
(nonzero), 01B (zero), or 10B (special).
如果您在任何 XMM 代码之前使用 emms
,则标签将全部为 11b(空)。
一旦 movq mm0, [qVar1]
被执行,所有标签都设置为 00b(有效)。
当执行 fstenv
时,寄存器被标记为非空并分析它们的内容:所有寄存器 R1-R7 似乎为零,而如前所述,R0 包含一个特殊值及其在存储图像中的标记因此在内存中是 10b(特殊)。
第二本手册中 fstenv
的条目确实具有欺骗性,其伪代码写为
Operation
DEST[FPUControlWord] ← FPUControlWord;
DEST[FPUStatusWord] ← FPUStatusWord;
DEST[FPUTagWord] ← FPUTagWord;
DEST[FPUDataPointer] ← FPUDataPointer;
DEST[FPUInstructionPointer] ← FPUInstructionPointer;
DEST[FPULastInstructionOpcode] ← FPULastInstructionOpcode;
这根本不是真的。
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
此时ax
是0101 0101 0101 0110
但是从 Intel 手册,第 9.5.1 MMX 指令和 x87 FPU 标记字 部分,我引用:
After each MMX instruction, the entire x87 FPU tag word is set to valid (00B).
那么为什么 ax
不全是零?
您引用的部分继续说:
Chapter 12, “Intel® MMX™ Technology System Programming,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, provides additional information about the effects of x87 FPU and MMX instructions on the x87 FPU tag word.
实际上第三本手册12.2节阐明:
When an MMX instruction writes a value into an MMX register, at the same time, bits 64 through 79 of the corresponding floating-point register are set to all 1s.
指令movq mm0, [qVar1]
然后将寄存器R0
设置为0xffff_00000000_00000000这是一个无效的double extended precision从80387开始的浮点值(之前是正无穷大) .
这在以后很重要。
fstenv
指令不保存实际的标记字,而是解释寄存器和实际的标记字来计算将存储的标记字在记忆中。
然后将所有寄存器的标记字寄存器重置为空。
fstenv
对x87 FPU标签字的影响是:
Tags and register values are read and interpreted; then all tags are set to 11B.
而内存中存储的x87 FPU tag word的图像为:
Tags are set according to the actual values in the floating-point registers; that is, empty registers are marked 11B and valid registers are marked 00B (nonzero), 01B (zero), or 10B (special).
如果您在任何 XMM 代码之前使用 emms
,则标签将全部为 11b(空)。
一旦 movq mm0, [qVar1]
被执行,所有标签都设置为 00b(有效)。
当执行 fstenv
时,寄存器被标记为非空并分析它们的内容:所有寄存器 R1-R7 似乎为零,而如前所述,R0 包含一个特殊值及其在存储图像中的标记因此在内存中是 10b(特殊)。
第二本手册中 fstenv
的条目确实具有欺骗性,其伪代码写为
Operation
DEST[FPUControlWord] ← FPUControlWord;
DEST[FPUStatusWord] ← FPUStatusWord;
DEST[FPUTagWord] ← FPUTagWord;
DEST[FPUDataPointer] ← FPUDataPointer;
DEST[FPUInstructionPointer] ← FPUInstructionPointer;
DEST[FPULastInstructionOpcode] ← FPULastInstructionOpcode;
这根本不是真的。