24.3 比较式的例子

  1. double d_max (double a, double b)
  2. {
  3. if (a>b)
  4. return a;
  5. return b;
  6. };

清单 24.5: MSVC 2012 x64 /Ox

  1. a$ = 8
  2. b$ = 16
  3. d_max PROC
  4. comisd xmm0, xmm1
  5. ja SHORT $LN2@d_max
  6. movaps xmm0, xmm1
  7. $LN2@d_max:
  8. fatret 0
  9. d_max ENDP

优化过的MSVC产生了很容易理解的代码。 COMISD是“Compare Scalar Ordered Double-Precision Floating-Point Values and Set EFLAGS”(比较标量双精度浮点数的值然后设置EFLAG)的缩写,显然,看着名字就知道他要干啥了。 非优化的MSVC代码产生了更加丰富的代码,但是仍然不难理解:

清单 24.6: MSVC 2012 x64

  1. a$ = 8
  2. b$ = 16
  3. d_max PROC
  4. comisd xmm0, xmm1
  5. ja SHORT $LN2@d_max
  6. movaps xmm0, xmm1
  7. $LN2@d_max:
  8. fatret 0
  9. d_max ENDP

但是,GCC 4.4.6生成了更多的优化代码,并且使用了MAXSD(“Return Maximum Scalar Double-Precision Floating-Point Value”,返回最大的双精度浮点数的值)指令,它将选中其中一个最大数。

清单24.7: GCC 4.4.6 x64 -O3

  1. a$ = 8
  2. b$ = 16
  3. d_max PROC
  4. movsdx QWORD PTR [rsp+16], xmm1
  5. movsdx QWORD PTR [rsp+8], xmm0
  6. movsdx xmm0, QWORD PTR a$[rsp]
  7. comisd xmm0, QWORD PTR b$[rsp]
  8. jbe SHORT $LN1@d_max
  9. movsdx xmm0, QWORD PTR a$[rsp]
  10. jmp SHORT $LN2@d_max
  11. $LN1@d_max:
  12. movsdx xmm0, QWORD PTR b$[rsp]
  13. $LN2@d_max:
  14. fatret 0
  15. d_max ENDP