• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            coreBugZJ

            此 blog 已棄。

            匯編調(diào)用 C 語(yǔ)言 printf %f 輸出浮點(diǎn)數(shù) float 的問(wèn)題:4字節(jié) 還是 8字節(jié)


             1 
             2 // 畢業(yè)論文做Pascal編譯器,把編譯生成的中間代碼翻譯為 nasm 匯編調(diào)用 C 語(yǔ)言庫(kù)函數(shù)時(shí),在輸出 float 部分出現(xiàn)問(wèn)題。
             3 
             4 
             5 // 先說(shuō)明一下,我安排棧中數(shù)據(jù) 8字節(jié)對(duì)齊,不管數(shù)據(jù)實(shí)際大小,都分配 8字節(jié),按最低字節(jié)尋址。
             6 // 當(dāng)然,調(diào)用 C 語(yǔ)言函數(shù)時(shí)的參數(shù)棧,還是按 i386 的來(lái)。
             7 
             8 
             9 // C printf 格式化字符串
            10 data.add( head + "c_format_float32 : db \'%f\', 0" );
            11 data.add( head + "c_format_float64 : db \'%lf\', 0" );
            12 data.add( head + "c_format_float64G: db \'%G\', 0" );
            13 
            14 
            15 // 棧頂已經(jīng)是 8字節(jié)的 ieee754 double 數(shù)據(jù),然后
            16 text.add( line + "push dword c_format_float64G" );
            17 // 或 text.add( line + "push dword c_format_float64" ); 也正確
            18 text.add( head + "call printf" );
            19 text.add( head + "add esp, 12" );
            20 // 生成可執(zhí)行文件后,運(yùn)行輸出正確
            21 
            22 
            23 // 棧頂已經(jīng)是 4字節(jié)的 ieee754 float 數(shù)據(jù),且不等于0(次棧頂 4字節(jié)全零),然后
            24 text.add( line + "push dword c_format_float32" );
            25 text.add( head + "call printf" );
            26 text.add( head + "add esp, 12" );
            27 // 生成可執(zhí)行文件后,運(yùn)行輸出 0.000000
            28 
            29 
            30 // 正確的是
            31 // 棧頂已經(jīng)是 4字節(jié)的 ieee754 float 數(shù)據(jù),然后
            32 // 先把4字節(jié)的float 轉(zhuǎn)為 8字節(jié)的double
            33 text.add( line + "fld dword [esp]" );
            34 text.add( head + "fstp qword [esp]" ); // 8字節(jié)對(duì)齊,未覆蓋棧中數(shù)據(jù)
            35 text.add( head + "push dword c_format_float32" );
            36 text.add( head + "call printf" );
            37 text.add( head + "add esp, 12" );
            38 // 生成可執(zhí)行文件后,運(yùn)行輸出正確
            39 
            40 

            結(jié)論:
             C 語(yǔ)言的 printf 使用 %f 來(lái)輸出 float 時(shí),實(shí)際上先把 4字節(jié)的float轉(zhuǎn)化為 8字節(jié)的double,然后訪問(wèn)了棧上的 8字節(jié)數(shù)據(jù)。

            (環(huán)境:Ubuntu12.04 32位 intel i3 nasm gcc)

            posted on 2013-04-29 16:51 coreBugZJ 閱讀(3188) 評(píng)論(2)  編輯 收藏 引用 所屬分類: AssembleLinuxCPUGPUProgrammingLanguage

            Feedback

            # re: 匯編調(diào)用 C 語(yǔ)言 printf %f 輸出浮點(diǎn)數(shù) float 的問(wèn)題:4字節(jié) 還是 8字節(jié) 2013-05-09 19:17 ilvu

            印象里可變參數(shù)壓棧是4字節(jié)對(duì)齊的。試一試char作為參數(shù)看看。  回復(fù)  更多評(píng)論   

            # re: 匯編調(diào)用 C 語(yǔ)言 printf %f 輸出浮點(diǎn)數(shù) float 的問(wèn)題:4字節(jié) 還是 8字節(jié) 2013-05-09 22:34 coreBugZJ

            @ilvu
            i386的參數(shù)原則上全都放在棧中,是4字節(jié)對(duì)齊的,char和short也是4字節(jié)對(duì)齊。  回復(fù)  更多評(píng)論   


            99精品久久久久久久婷婷| 麻豆精品久久精品色综合| 久久这里只精品国产99热| 国产成人久久激情91| 国产精品丝袜久久久久久不卡| 国产精品亚洲综合专区片高清久久久| 国内精品久久久久久麻豆| 国色天香久久久久久久小说| 婷婷综合久久中文字幕蜜桃三电影| 国产精品成人99久久久久91gav| 久久久噜噜噜久久| 大蕉久久伊人中文字幕| 久久亚洲国产精品成人AV秋霞| 亚洲一区二区三区日本久久九| 久久99久国产麻精品66| 亚洲国产精品成人久久蜜臀| 狠狠狠色丁香婷婷综合久久俺| 久久九九免费高清视频| 亚洲精品成人久久久| 久久久综合香蕉尹人综合网| 国产精品久久久久国产A级| AV无码久久久久不卡蜜桃| 伊人丁香狠狠色综合久久| 久久er国产精品免费观看2| 久久久久国产精品嫩草影院| 日韩人妻无码一区二区三区久久| 人人狠狠综合久久亚洲88| 久久香蕉国产线看观看乱码| 中文字幕无码久久人妻| 91久久精品91久久性色| 久久综合久久伊人| 99久久精品国产麻豆| 亚洲国产日韩综合久久精品| 久久这里只有精品久久| 少妇高潮惨叫久久久久久| 一级a性色生活片久久无少妇一级婬片免费放 | 久久久久国产精品人妻| 2021精品国产综合久久| 久久香综合精品久久伊人| 亚洲国产日韩欧美综合久久| 久久久久亚洲AV无码去区首|