《Windows 用戶態程序高效排錯》市場價元 特價元 購買>>
讀懂機器的語言匯編CPU執行指令的最小單元
需要用匯編來排錯的常見情況
匯編是CPU執行指令的最小單元下面一些情況下匯編級別的分析通常是必要的
閱讀代碼看不出問題但是跑出來的結果就是不對懷疑編譯器甚至CPU有毛病
沒有源代碼可以閱讀比如調用某一個API的時候出問題沒有Windows的源代碼那就看匯編
當程序崩潰訪問違例的時候調試器裡看到的直接信息就是匯編
調試中涉及的匯編知識分為兩部分
寄存器的運算對內存地址的尋址和讀寫這部分是跟CPU本身相關的
函數調用時候堆棧的變化局部變量全局變量的定位虛函數的調用這部分是跟編譯器相關的
案例分析用匯編讀懂VC編譯器的優化
問題描述
客戶在開發一個性能敏感的程序想知道VC編譯器對下面這段代碼的優化做得怎麼樣
int hgt=;
int wid=;
for (i=; i<hgt; i++)
for (j=; j<wid; j++)
A[i*wid+j] = exp((i*i+j*j));
最直接的方法就是查看編譯器生成的匯編代碼分析有興趣的話先自己調試一下看看跟我的分析是否一樣
這段代碼涉及到的優化有
i*i在每次內循環中是不變化的所以只需要在外循環裡面重新計算編譯器把外循環計算好的i*i放到ebx寄存器中內循環直接使用
對A[i*wid+j]尋址的時候在內循環裡面變化的只有j而且每次j都是增加由於A是整型數組所以每次尋址的變化就是增加*sizeof (int)就是編譯器把i*wid+j的結果放到了EDI中在內循環中每次add edi來實現了這個優化
對於中間變量編譯器都是保存在寄存器中並沒有讀寫內存
如果這段匯編讓你手動來寫你能做得比編譯器更好一點嗎?
案例分析VC 編譯器的bugdebug模式正常release模式會崩潰
不要迷信編譯器沒有bug如果你在VS中測試下面的代碼會發現在release mode下面程序會崩潰或者異常但是在debug mode下工作正常
程序中除了cout和printf外沒有牽涉到系統相關的API所有的操作都是寄存器和內存上的操作所以不會是環境或者系統因素導致的可能性是代碼錯誤(比如邊界問題)或者編譯器有問題
檢查代碼後沒有發現異常同時如果調整一下std::transform的位置在for loop後面調用的話問題就不會發生
問題發生的情況跟編譯模式相關
[] [] []
From:http://tw.wingwit.com/Article/os/xtgl/201311/10161.html