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的十進制值。
如果對printf實作不是很了解,可以參考http://blog.csdn.net/fzp218/article/details/7375427
總結: 适當知道點彙編還是挺重要的,像這種在進階語言層面看不清的問題,一看彙編就明了了。