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
但根据英特尔手册9.5.1MMX指令和x87 FPU标签字,我引用如下:
在每个MMX指令之后,整个x87 FPU标签字被设置为有效(00B)。
那么,为什么ax不是全部为零呢?
发布于 2017-06-24 19:12:10
你引用的那一节继续说:
第12章,“Intel MMX技术系统编程”,载于Intel 64和IA-32架构软件开发人员手册第3A卷,其中提供了关于 x87 FPU和MMX指令对 x87 FPU标签word的影响的附加信息。
事实上,第三本手册第12.2节澄清:
当MMX指令将值写入MMX寄存器时,同时将相应的浮点寄存器的64到79位设置为所有1s。
指令movq mm0, [qVar1]然后将寄存器R0设置为0xffff_00000000_00000000,这是一个无效的双扩展精度浮点值,从80387开始(以前是一个正无穷大)。
这以后就很重要了。
fstenv指令不保存实际的标记词,而是解释寄存器和实际的标记词,以计算将存储在内存中的标记字。
然后,对所有寄存器将标记字寄存器重置为空。
fstenv对x87 FPU标签字的影响是:
对标记和寄存器值进行读取和解释,然后将所有标记设置为11B。
存储在内存中的x87 FPU标签字的图像是:
标签是根据浮点寄存器中的实际值来设置的;也就是说,空寄存器被标记为11B,有效寄存器被标记为00B (非零)、01B (零)或10B (特殊)。

如果在任何XMM代码之前使用emms,则标记将全部为11b (空)。
一旦执行movq mm0, [qVar1],所有标记都被设置为00b (有效)。
执行fstenv时,寄存器被标记为不为空,并对其内容进行分析:所有寄存器R1-R7似乎为零,而前面看到的R0包含一个特殊值,存储在内存中的图像中的标记为10b (特殊)。
诚然,第二本手册中的fstenv条目具有欺骗性,因为它的伪代码被写成
操作 DESTFPUControlWord←FPUControlWord; DESTFPUStatusWord←FPUStatusWord; DESTFPUTagWord←FPUTagWord; DESTFPUDataPointer←FPUDataPointer; DESTFPUInstructionPointer←FPUInstructionPointer; DESTFPULastInstructionOpcode←FPULastInstructionOpcode;
这根本不是真的。
https://stackoverflow.com/questions/44738755
复制相似问题