ax
此时0101 0101 0101 0110
为ax
但是,从英特尔手册, 9.5.1 MMX说明和x87 FPU标记词部分,我引用:
在每条MMX指令之后,整个x87 FPU标记字设置为有效(00B)。
那么为什么{{1}}不是全零呢?
答案 0 :(得分:5)
你引用的部分继续说:
英特尔®64和IA-32架构软件中的第12章“英特尔®MMX™技术系统编程” 开发人员手册,第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;
这根本不是真的。