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

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

上天者,搬出枕頭厚的大部頭引經(jīng)據(jù)點(diǎn),說有Lipman某典故云云;又有C++標(biāo)準(zhǔn)M頁N條款如是說...

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

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

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

——喝口茶先,大家先看看秋鎮(zhèn)菜blog上這篇文章《在 Visual C++ 中使用內(nèi)聯(lián)匯》 ,詳細(xì)介紹了在 Visual C++ 中內(nèi)聯(lián)匯編的用法。

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




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

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

好嘛,看看簡(jiǎn)潔的Release模式 —— orz.... 不能單步跟蹤C(jī)++程序了? 連main函數(shù)在哪里都看不見... 瞎了...

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

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

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

_TEXT SEGMENT // 代碼段開始標(biāo)志
_TEXT ENDS // 代碼段結(jié)束標(biāo)志

對(duì)于觀察每個(gè)函數(shù)的生成代碼來說,這兩個(gè)標(biāo)志能起到路標(biāo)的作用。


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

2 匯編訪問類成員
若有一個(gè)類

class A{
int _i;
};

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

__asm mov [a]A._i, 10

但是在A 的成員函數(shù)中怎么辦呢?

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

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

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

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

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

另一方面,雖然在我們的確寫了大大的“ inline ”幾個(gè)字,但是看看輸出代碼——你會(huì)發(fā)現(xiàn):任何包含了內(nèi)嵌匯編的 inline 成員函數(shù)都不會(huì)被內(nèi)聯(lián)!


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

3 匯編/內(nèi)聯(lián)函數(shù)和效率


普通函數(shù)是可以內(nèi)聯(lián)的,下面就是一個(gè)完美的結(jié)合 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自開機(jī)運(yùn)行的時(shí)鐘周期數(shù)。它的結(jié)果是64位的,保存到 eax 和 edx兩個(gè)寄存器中,可以用來精確測(cè)量算法開銷。上面的函數(shù)內(nèi)聯(lián)之后, 局部變量不見了, 臨時(shí)返回值也不見了,只有最核心的三行代碼,沒有比這更簡(jiǎn)潔的了:

; 68 : long long b = getTimer();

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

成員函數(shù)內(nèi)聯(lián)則又是另一個(gè)故事:系統(tǒng)不知道如何處理this,所以他干脆忽略所有內(nèi)嵌asm成員函數(shù)的內(nèi)聯(lián)標(biāo)志。

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

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

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

要正確編寫能成功內(nèi)聯(lián)的代碼必須結(jié)合另一個(gè)方案,手動(dòng)復(fù)制this:

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

厄。。。猜猜看結(jié)果如何?

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

; 56 : a.i( 5 );

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

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

; 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

這么長啊....生出一個(gè)怪胎... VC 中嵌入?yún)R編的一個(gè)壞處是:編譯器很難將他和C++協(xié)調(diào),很難優(yōu)化他。

匯編優(yōu)化可以很快速、很強(qiáng),但是一定要慎用。
posted on 2008-07-23 16:28 chatler 閱讀(139) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++_BASIS
<2010年2月>
31123456
78910111213
14151617181920
21222324252627
28123456
78910111213

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個(gè)博客還是不錯(cuò),雖然做的東西和我不大相關(guān),覺得看看還是有好處的

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

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美激情91| 香港久久久电影| 久久国产精品久久国产精品| 久久九九99| 亚洲成色精品| 亚洲综合第一| 欧美激情中文字幕乱码免费| 欧美成人资源网| 亚洲综合日韩在线| 国产精品色一区二区三区| 欧美日韩国产在线一区| 亚洲专区免费| 欧美日韩视频一区二区三区| 欧美日韩综合一区| 亚洲精品你懂的| 久久深夜福利| 欧美综合77777色婷婷| 欧美成年人视频网站| 亚洲经典三级| 久久免费国产| 亚洲第一网站免费视频| 久久亚洲一区| 一区二区久久久久| 亚洲国产激情| 亚洲国产va精品久久久不卡综合| 久久久久久穴| 欧美日韩国产在线看| 欧美大成色www永久网站婷| 久久精品国内一区二区三区| 99re66热这里只有精品4| 亚洲欧美激情视频| 亚洲第一网站免费视频| 老色鬼精品视频在线观看播放| 亚洲人午夜精品免费| 亚洲人精品午夜| 在线播放国产一区中文字幕剧情欧美| 久久久av毛片精品| 亚洲三级国产| 欧美日韩国产丝袜另类| 亚洲第一精品久久忘忧草社区| 免费不卡在线观看| 欧美激情综合| 免费欧美电影| 国产日韩欧美综合一区| 亚洲欧洲一区二区三区久久| 国产日产欧产精品推荐色 | 欧美在线观看视频一区二区三区 | 夜夜爽av福利精品导航| 欧美大片国产精品| 亚洲女女做受ⅹxx高潮| 欧美理论在线| 亚洲视屏在线播放| 欧美在线999| 欧美电影资源| 一区二区三区成人| 欧美视频在线免费看| 亚洲美女av在线播放| 国产日韩精品一区观看| 另类春色校园亚洲| 亚洲视频一区在线观看| 亚洲一区二区3| 欧美日韩三级| 亚洲国产日韩综合一区| 91久久精品国产91久久性色tv| 蜜臀久久99精品久久久久久9 | 欧美成人国产一区二区| 美女视频黄a大片欧美| 狠色狠色综合久久| 欧美专区日韩视频| 模特精品裸拍一区| 日韩视频免费在线观看| 久久国产精品一区二区| 99视频精品全国免费| 欧美成人性网| 日韩视频一区二区| 亚洲欧美制服另类日韩| 久久久久久久久久久一区| 亚洲色图在线视频| 久久aⅴ国产紧身牛仔裤| 激情久久久久久久| 欧美性片在线观看| 国产精品成人一区二区网站软件 | 国产精品国产三级国产专播品爱网| 欧美一区视频在线| 亚洲一区二区三区国产| 亚洲视频www| 欧美专区中文字幕| 卡一卡二国产精品| 一区二区三区高清| 亚洲一区免费在线观看| 欧美婷婷在线| 亚久久调教视频| 亚洲日本久久| 开心色5月久久精品| 美女图片一区二区| 午夜在线成人av| 亚洲国产毛片完整版| 国产一区二区三区在线观看网站| 国产精品久久久99| 国产欧美精品在线播放| 国产亚洲精品久久久久久| 亚洲欧美日韩综合aⅴ视频| 狠狠色狠狠色综合系列| 欧美日韩亚洲一区二区三区在线 | 亚洲国产精品成人一区二区| 99国产精品| 久久riav二区三区| 狼人社综合社区| 久久久精品久久久久| 国产综合自拍| 亚洲欧洲一区二区天堂久久| 乱中年女人伦av一区二区| 免费成人黄色av| 久久美女性网| 裸体歌舞表演一区二区| 久久久青草青青国产亚洲免观| 久久成人精品| 欧美激情a∨在线视频播放| 久久激情视频免费观看| 欧美在线视频日韩| 亚洲天堂黄色| 久久婷婷人人澡人人喊人人爽| 久久福利毛片| 久久久中精品2020中文| 久久综合伊人77777尤物| 欧美激情欧美激情在线五月| 91久久久在线| 激情六月婷婷久久| 蜜臀91精品一区二区三区| 亚洲一区二区高清| 亚洲国产一区二区三区在线播 | 99ri日韩精品视频| 亚洲精品一区二区网址| 亚洲曰本av电影| 美女精品自拍一二三四| 欧美大片在线看免费观看| 夜夜嗨av一区二区三区网页| 欧美亚洲在线观看| 欧美亚州一区二区三区| 亚洲黄色性网站| 久久精品一区二区三区不卡牛牛| 亚洲国产精品va| 欧美一区二区三区视频免费| 欧美视频一区二| 亚洲另类视频| 亚洲国产欧美不卡在线观看| 亚洲欧美国内爽妇网| 欧美性淫爽ww久久久久无| 亚洲高清久久网| 蜜桃av综合| 欧美成人激情视频| 夜夜嗨一区二区三区| 亚洲精选在线观看| 欧美成人亚洲成人| 亚洲日本成人在线观看| 亚洲黄色在线视频| 欧美日韩国产丝袜另类| 亚洲性人人天天夜夜摸| 国产精品一区二区你懂的| 欧美在线视频观看免费网站| 亚洲一级免费视频| 国产精品一区视频| 免费观看久久久4p| 欧美日韩国产一中文字不卡| 在线一区欧美| 久久精品99无色码中文字幕| 亚洲高清激情| 亚洲欧美久久| 亚洲国产专区校园欧美| 欧美激情国产高清| 国产精品久久国产三级国电话系列| 欧美一级免费视频| 中文日韩在线| 美女精品一区| 欧美在线高清视频| 欧美日韩国产一区二区三区地区 | 夜夜嗨av色综合久久久综合网 | 亚洲一区二区三区高清不卡| 久久av在线看| 欧美一区二区在线免费播放| 欧美激情一二区| 麻豆乱码国产一区二区三区| 国产精品色婷婷| 日韩一二三在线视频播| 亚洲国产天堂久久综合网| 亚洲手机在线| 亚洲欧美中日韩| 欧美激情1区| 最新亚洲激情| 亚洲视频狠狠| 欧美日韩综合久久| 这里只有视频精品| 亚欧成人在线| 国产午夜精品在线观看| 亚洲视频碰碰| 久久久久久国产精品一区| 亚洲电影第三页| 欧美久久视频| 欧美在线首页| 日韩视频国产视频|