3.11.4 定义和使用浮点常数
3.11.4 定义和使用浮点常数
和整数运算操作不同,AVX 浮点操作不能以立即数值作为操作数。相反,编译器必须为所有的常量值分配和初始化存储空间。然后代码再把这些值从内存读入。下面从摄氏度到华氏度转换的函数就说明了这个问题:
double cel2fahr(double temp)
{
return 1.8 * temp + 32.0;
}相应的 x86-64 汇编代码部分如下:
double cel2fahr(double temp)
temp in %xmm0
1 cel2fahr:
2 vmulsd .LC2(%rip), %xmm0, %xmm0 Multiply by 1.8
3 vaddsd .LC3(%rip), %xmm0, %xmm0 Add 32.0
4 ret
5 .LC2:
6 .long 3435973837 Low-order 4 bytes of 1.8
7 .long 1073532108 High-order 4 bytes of 1.8
8 .LC3:
9 .long 0 Low-order 4 bytes of 32.0
10 .long 1077936128 High-order 4 bytes of 32.0
可以看到函数从标号为 .LC2 的内存位置读出值 1.8,从标号为 .LC3 的位置读入值 32.0。观察这些标号对应的值,可以看出每一个都是通过一对 .long 声明和十进制表示的值指定的。该怎样把这些数解释为浮点值呢?看看标号为 .LC2 的声明,有两个值:3435973837(0xcccccccd)和 1073532108(0x3ffccccc)。因为机器采用的是小端法字节顺序,第一个值给出的是低位 4 字节,第二个给出的是高位 4 字节。从高位字节,可以抽取指数字段为 0x3ff(1023),减去偏移 1023 得到指数 0。将两个值的小数位连接起来,得到小数字段 0xccccccccccccd,二进制小数表示为 0.8,加上隐含的 1 得到 1.8。
练习题 3.55 解释标号为 .LC3 处声明的数字是如何对数字 32.0 编码的。