float value = 1.0;
printf("value_int = %d\n", value);


 


对于上面的代码,会输出什么结果呢?( 结果是0,当然这跟你的计算机是大端还是小端有关,大小端分析一样,这里是以小端为例)是不是觉得很奇怪,value的浮点数表示形式是 0x3F800000,如果以整形输出,应该也是这个值的十进制表示才对的。




单精度浮点数表示是:1位符号,8位阶码,23位尾数: 1.0的符号位是0,注意1.0的整数位1省略了,所以尾数全是0,而阶码是移码表示,所以是1+127,参考


双精度浮点数表示是:1位符号,11位阶码,52位尾数:如果是double value,则value的表示形式是 0x3FF0000000000000


关于浮点数的机器表示参考: ​​http://zh.wikipedia.org/wiki/IEEE_754​​ 



分析上面代码的汇编实现:(这里是VS下的反汇编代码,关注标红部分及下面的解释就行)



float value = 1.0;汇编代码如下:


004113BE   fld1         


//向浮点器特殊寄存器st7(64位)中初始化值为1的浮点数(双精度)     


004113C0   fstp        dword ptr [value]  


//从浮点器特殊寄存器st7中载入数值到value中,注意这里是dword(32位),作了双精度到单精度的转换


 


printf("value_int = %d\n", value);汇编代码如下:


004113C3   fld         dword ptr [value] 


//向浮点器特殊寄存器st7(64位)中存入单精度value


004113C6  mov         esi,esp 


004113C8  sub         esp,8 


004113CB   fstp        qword ptr [esp]


//从浮点器特殊寄存器st7中载入数值(value的双精度)到esp指向的地址中,注意这里是qword(64位),所以不用转换 


004113CE  push        offset string "value_int = %d\n" (415800h) 


004113D3  call        dword ptr [__imp__printf (4182BCh)] 


004113D9  add         esp,0Ch




上面的代码把1的双精度值压入了栈中,而我的计算机又是小端的,那么内存从从低到高字节依次是


00 00 00 00 00 00 F0 3F(即0x3FF0000000000000以字节为单位倒置)



当printf检测到%d要输出整形时,取到的值是00 00 00 00,所以这就不难理解为什么结果是0了。如果是大端,那么输出0x3FF00000的十进制值。





总结:


适当知道点汇编还是挺重要的,像这种在高级语言层面看不清的问题,一看汇编就明了了。