青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 297,  comments - 15,  trackbacks - 0
在Ailiss社區與人爭論語法,終極武器不外乎兩把 —— 上天入地。

上天者,搬出枕頭厚的大部頭引經據點,說有Lipman某典故云云;又有C++標準M頁N條款如是說...

入地者,操起起子扳手把程序拆個凄涼八落,啪啪啪回上一大片編譯器匯編的輸出,說——看吧,都在這里了。

事實上,我發覺兩者對于深入理解C++都是必不可少的。前些時,論壇上突然流行討論數組的本質。怪的是,每次我以為自己真的懂了,下一次又卻發現自己的輕浮。等到通曉實現細節,再回過頭來看最土的C教材的定義,竟發現字字璣珠。

最近對入地頗感興趣,動輒查匯編,寫了不少混合代碼研究語法。放下扳手抹抹鼻尖上的機油,倒是有些心得。各位看官——我就要跟大家亂侃近來入地一個多月,邪門歪地道挖出雜七雜八的東西——的工具——就 匯編。

——喝口茶先,大家先看看秋鎮菜blog上這篇文章《在 Visual C++ 中使用內聯匯》 ,詳細介紹了在 Visual C++ 中內聯匯編的用法。

參考書也必不可少;可悲的是我手頭僅有的兩本書一本是老掉牙的8086匯編,另一本則是AT&T語法的 —— 廣泛用于Linux上的編譯器, 但VC 偏要使用Inter語法.... 帶來麻煩不少,希望大家慷慨解囊之前先看準。




--------------------------------------------------------------------------------

1 察看編譯器輸出
通常來說,Debug 模式單步跟蹤時Alt+8 就可以看見匯編代碼。問題是 Debug 只是代表了一個側面,并不代表最終的 Release ;另一方面 Debug 模式包含了些許額外的測試代碼 —— 恩,可能代碼有些多...天啊,他們干嘛要加、那么多、莫名其妙的代碼混淆視聽阿!

好嘛,看看簡潔的Release模式 —— orz.... 不能單步跟蹤C++程序了? 連main函數在哪里都看不見... 瞎了...

Release 模式單步跟蹤要需要高深的技術底氣。不過也沒那么絕,要看 Release 模式的輸出,我們可以在項目屬性->C/C++->輸出文件頁面中把“匯編輸出”項定為“帶源代碼的程序集(/FAs)”。這樣,在Release目錄下就可以看見對應的asm文件了。看asm文件,唯一的缺點是不能單步跟蹤研究。

這個asm文件搞不好會非常大——主要是由于C++標準庫廣泛使用模板的原因,若我們放棄C++庫一律使用C標準庫就會看到很干凈的asm文件(同時會看見一個1/4大小的可執行文件,你會明白為什么那么多人支持C )——當然這不是C++的干活。 要在這個動輒數W行的文件中里面找源代碼對應的匯編,推薦大家找一行一定不會被優化掉的代碼(沒錯,某些代碼可能人間蒸發),直接F3搜索。

asm中包含了很多注釋,有基本的匯編知識然后連蒙帶猜就能看懂了。一對挺有用的標志是:

_TEXT SEGMENT // 代碼段開始標志
_TEXT ENDS // 代碼段結束標志

對于觀察每個函數的生成代碼來說,這兩個標志能起到路標的作用。


--------------------------------------------------------------------------------

2 匯編訪問類成員
若有一個類

class A{
int _i;
};

有A 的實例a,下面的代碼令 a._i = 10,這只需要一個指令:

__asm mov [a]A._i, 10

但是在A 的成員函數中怎么辦呢?

我們知道,成員函數調用為 thiscall, this通過 ecx傳遞。所以在函數的開頭現場尚未被破壞的時候,可以直接用 ecx 變址訪問。如下面是一個常見的set函數, 它令 A::_i = n (注意mov等指令中,兩個操作數不能同時為內存內容,所以必須用寄存器eax接力):

inline void A::i( int n ){
__asm mov eax, n
__asm mov [ecx]A._i, eax
}

不過這有兩個問題。一來,ecx并非總是this;它隨時可能被刷掉。在某個不能確定保存this寄存器的時候,你需要手動寫ecx:

__asm mov ecx, this
__asm mov eax, n
__asm mov [ecx]A._i, eax

這樣寫會迫使編譯器把this的值復制到棧上 —— 而一般來說對于小函數而言,編譯器會盡量只用寄存器。這可能是一個額外的小小開銷。(注意,千萬不要以為可以這么訪問: [this]A._i )

另一方面,雖然在我們的確寫了大大的“ inline ”幾個字,但是看看輸出代碼——你會發現:任何包含了內嵌匯編的 inline 成員函數都不會被內聯!


--------------------------------------------------------------------------------

3 匯編/內聯函數和效率


普通函數是可以內聯的,下面就是一個完美的結合 C++/ asm 的例子:

inline long long getTimer(){
long long time;
__asm rdtsc
__asm mov DWORD PTR time, eax
__asm mov DWORD PTR time + 4, edx
return time;
}

rdtsc指令用來獲得CPU自開機運行的時鐘周期數。它的結果是64位的,保存到 eax 和 edx兩個寄存器中,可以用來精確測量算法開銷。上面的函數內聯之后, 局部變量不見了, 臨時返回值也不見了,只有最核心的三行代碼,沒有比這更簡潔的了:

; 68 : long long b = getTimer();

rdtsc
mov DWORD PTR _time$11298[ebp], eax
mov DWORD PTR _time$11298[ebp+4], edx

成員函數內聯則又是另一個故事:系統不知道如何處理this,所以他干脆忽略所有內嵌asm成員函數的內聯標志。

好嘛,VC不愿上,我們用皮鞭趕著他上! 把第二部分最初那個 A::i 改為 __forceinline 就強制內聯了——也就是強制VC犯錯誤了:不幸的編譯器看不懂我們的代碼,只好把指令抄到函數調用處。他不曉得初始化ecx,那個mov可能往任何地方寫內容——比如把你的開機密碼寫到桌面上——

雖然可以手動設置ecx,不過我們可不希望看見如此丑陋的調用(想象一下你的同事看到這段代碼的困惑):

__asm lea ecx, a
a.i( 20 );

要正確編寫能成功內聯的代碼必須結合另一個方案,手動復制this:

__forceinline void A::i( int n ){
__asm mov ecx, this
__asm mov eax, n
__asm mov [ecx]A._i, eax
}

厄。。。猜猜看結果如何?

首先看看我們直接用C++寫一個 set函數 (譬如 void A::i( int n ){ _i = n; } )內聯后的結果:

; 56 : a.i( 5 );

mov DWORD PTR _a$[ebp+8], 5

最殘酷的結果也只需一句mov。 更可能的結果是——他被優化得連影兒都看不見。
然后看看我們的三年懷胎含辛茹苦研究出來的混合匯編的內聯:

; 56 : a.i( 5 );

lea eax, DWORD PTR _a$[ebp]
pop ecx
mov DWORD PTR $T11194[ebp], eax
mov ecx, DWORD PTR $T11194[ebp]
mov eax, 5
mov DWORD PTR [ecx+8], eax

這么長啊....生出一個怪胎... VC 中嵌入匯編的一個壞處是:編譯器很難將他和C++協調,很難優化他。

匯編優化可以很快速、很強,但是一定要慎用。
posted on 2008-07-23 16:28 chatler 閱讀(139) 評論(0)  編輯 收藏 引用 所屬分類: C++_BASIS
<2010年8月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美一站二站| 一本一本久久a久久精品综合妖精| 欧美国产视频在线观看| 一区二区91| 亚洲精品乱码久久久久久蜜桃麻豆 | 伊人久久综合| 欧美激情一区二区三区在线视频| 毛片基地黄久久久久久天堂| 亚洲每日更新| 亚洲亚洲精品三区日韩精品在线视频| 国产精品久久久久久久电影 | 亚洲中字黄色| 性欧美暴力猛交69hd| 亚洲高清不卡在线| aaa亚洲精品一二三区| 国产欧美日韩亚洲一区二区三区| 久久久五月婷婷| 欧美a级片一区| 亚欧成人在线| 男女激情久久| 久久久久国产成人精品亚洲午夜| 久热这里只精品99re8久| 夜夜夜精品看看| 性做久久久久久| 日韩香蕉视频| 久久精品1区| 亚洲一区国产精品| 久久一区欧美| 欧美亚洲一区在线| 欧美精品在线一区二区三区| 欧美在线91| 欧美日韩在线不卡| 欧美成熟视频| 国产视频观看一区| 亚洲美洲欧洲综合国产一区| 狠狠色噜噜狠狠色综合久| 一区二区三区回区在观看免费视频| 国产自产女人91一区在线观看| 亚洲精选久久| 亚洲欧洲另类| 久久久www成人免费毛片麻豆| 中文欧美日韩| 欧美成人69av| 免费黄网站欧美| 国产亚洲精久久久久久| 一区二区欧美激情| 日韩一级黄色片| 美女网站在线免费欧美精品| 久久久99精品免费观看不卡| 国产精品高潮呻吟久久av黑人| 亚洲大胆av| 亚洲国产欧美在线| 久久深夜福利免费观看| 久久久久久久综合日本| 国产精品每日更新在线播放网址| 亚洲精品精选| 亚洲伦理中文字幕| 欧美成人综合在线| 亚洲大片av| 亚洲精品视频一区| 欧美大片在线看免费观看| 久久亚洲电影| 黄色一区二区三区四区| 香蕉国产精品偷在线观看不卡| 欧美精品一区二| 亚洲午夜高清视频| 欧美精品久久久久久| 亚洲国产三级| 一本色道久久99精品综合 | 亚洲欧洲av一区二区三区久久| 亚洲一区二区在线播放| 国产精品福利网| 亚洲欧美日产图| 久久久久久一区二区| 狠狠色狠狠色综合日日小说| 久久婷婷蜜乳一本欲蜜臀| 免费亚洲电影在线观看| 亚洲国产精品一区制服丝袜| 欧美激情精品久久久久久久变态 | 久久久久久**毛片大全| 美女日韩欧美| 亚洲精品在线视频| 欧美日韩免费观看一区| 午夜精品一区二区三区四区| 久久久久看片| 亚洲人妖在线| 国产精品男gay被猛男狂揉视频| 欧美一区二区在线免费播放| 蜜臀久久99精品久久久画质超高清| 亚洲欧洲一区二区三区久久| 国产精品v日韩精品| 欧美在线一级va免费观看| 欧美多人爱爱视频网站| 一区二区欧美日韩视频| 国产乱码精品一区二区三区不卡| 久久精品亚洲| 亚洲视频999| 欧美成人a∨高清免费观看| 一本久久青青| 红桃视频一区| 欧美三级网页| 噜噜噜噜噜久久久久久91| 一本色道久久综合| 免费看黄裸体一级大秀欧美| 亚洲一区精品视频| 亚洲电影激情视频网站| 国产精品日韩精品欧美精品| 美国十次成人| 欧美一级精品大片| 亚洲久久一区| 欧美国产视频在线观看| 欧美亚洲免费电影| 99国产精品久久久久久久成人热| 国产网站欧美日韩免费精品在线观看 | 亚洲一区二区三区视频| 亚洲高清在线播放| 国产日韩精品视频一区| 欧美极品一区| 久久一区二区三区四区| 午夜久久福利| 亚洲一区免费看| 亚洲精品美女在线| 亚洲国产精品va在看黑人| 久久天天躁夜夜躁狠狠躁2022| 亚洲一区二区三区免费视频| 亚洲精选在线观看| 在线观看国产日韩| 国产在线精品一区二区夜色| 国产精品看片资源| 国产精品久久久久久av福利软件 | 久久精品国产免费| 在线视频你懂得一区| 亚洲国产精品一区二区www| 狠狠色综合网站久久久久久久| 国产精品每日更新| 国产精品美女| 国产精品久久久久高潮| 欧美性大战久久久久| 欧美日韩综合网| 欧美日韩国产精品自在自线| 欧美国产一区二区| 欧美精品一线| 欧美日韩情趣电影| 欧美日韩在线一区二区| 欧美日韩在线视频一区二区| 欧美无乱码久久久免费午夜一区| 欧美精品在线免费观看| 欧美日韩国产一中文字不卡| 欧美人体xx| 欧美系列电影免费观看| 国产精品久久久一区麻豆最新章节 | 国产一区亚洲| 黄色国产精品| 亚洲国产精品一区二区www| 亚洲精品乱码久久久久久蜜桃麻豆 | 亚洲激情视频在线播放| 最近中文字幕日韩精品| 亚洲精品一区二区在线观看| 亚洲精品一区二区三区在线观看| 99精品欧美一区二区三区| 亚洲视频久久| 欧美一区二区三区啪啪| 久久全球大尺度高清视频| 免费看精品久久片| 欧美午夜片在线观看| 国产欧美在线播放| 亚洲第一精品电影| 99视频一区| 欧美一区二区精品在线| 美女视频黄免费的久久| 亚洲伦伦在线| 欧美亚洲三级| 欧美高清免费| 国产精品一区二区在线观看网站| 国产主播一区二区| 亚洲人成在线免费观看| 亚洲男人的天堂在线| 久久手机精品视频| 亚洲精品激情| 久久久国产精品一区二区三区| 欧美国内亚洲| 国产日韩欧美综合精品| 亚洲精品久久久久久久久久久| 亚洲综合色丁香婷婷六月图片| 久久久久久伊人| 亚洲视频碰碰| 老色鬼精品视频在线观看播放| 欧美视频在线一区| 在线电影欧美日韩一区二区私密| 亚洲一区二区三区涩| 欧美激情精品久久久久久大尺度 | 亚洲女性裸体视频| 欧美成人亚洲| 亚洲免费小视频| 一本久久综合亚洲鲁鲁| 久久久精品国产免大香伊| 国产精品扒开腿做爽爽爽软件| 亚洲欧洲日夜超级视频| 久久久久久久999精品视频| 夜夜嗨网站十八久久|