【bug】warning #13200: No emms instruction before return from function
DATE: 2018.11.14
1、問題描述
採用Intel編譯器編譯使用MMX指令(Inline assembly)的彙編程式碼時,報下面的警告:
warning #13200: No emms instruction before return from function
2、分析和解決方案
Since MMX aliases over the floating-point registers, any routine that uses MMX instructions must end with the EMMS instruction. This instruction “clears” the registers, making them available for use by the x87 FPU once again. (Which any C or C++ calling convention for x86 will assume is safe.) The compiler is warning you that you have written a routine that uses MMX instructions but does not end with the EMMS instruction. That’s a bug waiting to happen, as soon as some FPU instruction tries to execute. This is a huge disadvantage of MMX, and the reason why you really can’t freely intermix MMX and floating-point instructions. Sure, you could just throw EMMS instructions around, but it is a slow, high-latency instruction, so this kills performance. SSE had the same limitations as MMX in this regard, at least for integer operations. SSE2 was the first instruction set to address this problem, since it used its own discrete register set. Its registers are also twice as wide as MMX’s are, so you can do even more at a time. Since SSE2 does everything that MMX does, but faster, easier, and more efficiently, and is supported by the Pentium 4 and later, it is quite rare that anyone needs to write new code today that uses MMX. If you can use SSE2, you should. It will be faster than MMX. Another reason not to use MMX is that it is not supported in 64-bit mode.
原因和風險: MMX,SSE都存在需要在使用完MMX,SSE指令返回函式之前使用emms指令,並且emms指令速度很慢。而SSE2沒有這個限制。存在這個限制的根本原因是MMX的整數暫存器使用的浮點暫存器的低位,在使用完整數暫存器之後,需要將浮點暫存器復位,否則在後面使用浮點暫存器時,會造成計算出錯。
Solution: Use the EMMS instruction (e.g. by calling the _mm_empty() intrinsic ) after the MMX instructions before the return to restore the Floating-point status on the CPU.