RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

編譯器如何對代碼進(jìn)行優(yōu)化(上)

jf_78858299 ? 來源:看雪論壇 彼岸風(fēng) ? 作者:看雪論壇 彼岸風(fēng) ? 2023-02-01 16:25 ? 次閱讀

在學(xué)習(xí) Andorid 逆向的過程中,發(fā)現(xiàn)無論是哪種編譯器,生成哪個平臺的代碼,其優(yōu)化思路在本質(zhì)上如出一轍,在 Windwos 平臺所使用的技巧,在安卓平臺仍然適用,不外乎乘法除法計算的優(yōu)化,swtich 判定樹的優(yōu)化,對 if 條件句的優(yōu)化,while 循環(huán)的優(yōu)化等等,編寫本文的目的也就是為了對已學(xué)的知識進(jìn)行總結(jié)。

這里強(qiáng)烈推薦老錢和老張寫的《C++匯編與逆向分析技術(shù)揭秘》,本文大部分知識點(diǎn)都將以此書作為參考,我個人是不太喜歡看直播和視屏教程的,因?yàn)橛行╆P(guān)鍵知識點(diǎn)可能老師一句話就帶過去了,要想回來看還得來回拉進(jìn)度條,但是書不一樣,遇到讀不懂的地方可以停下來仔細(xì)思考,想回頭看也就是翻幾頁的事情,遇到那種寫的特別細(xì)的作者,那讀起來更是一種享受。

本文列舉的代碼和匯編只是為了更好的說明思路,并不代表實(shí)際代碼,好了話不多說,進(jìn)入正題。

優(yōu)化方向

  • 編譯速度優(yōu)化
  • 執(zhí)行速度優(yōu)化
  • 程序體積優(yōu)化

對于 Debug 版程序,編譯器為了滿足單步調(diào)試需求,不會對無意義的代碼進(jìn)行優(yōu)化。無意義的意思是沒有發(fā)生傳遞,沒有賦值到內(nèi)存空間。



常見的優(yōu)化類型

常量折疊

更像是預(yù)處理,編譯器會將所有可預(yù)見的值直接寫成立即數(shù)。

int n = 2 + 3 * 6;
// 編譯器在處理這段代碼時會直接將變量賦予立即數(shù)+
// mov n, 20

常量傳播

是常量折疊的“進(jìn)階版”,編譯器會掃描整個代碼段,對所有非變量運(yùn)算直接計算出結(jié)果。

int n = 2 + 3 * 6;
int m = n * 10;
// mov m, 200

減少變量

未使用即是無意義,無意義的代碼都會被優(yōu)化,上述的兩個示例,在實(shí)際編譯中是會直接被優(yōu)化掉的,因?yàn)椴⑽幢挥糜诤瘮?shù)傳參和其他操作。

編譯雖然能通過,但不會產(chǎn)生任何代碼,因?yàn)闆]有傳遞結(jié)果,對后續(xù)的代碼執(zhí)行不會造成任何影響。

int funtion1() {
    int n = 2 + 3 * 6;
    int m = n * 10;
    return 0;
}
// 無意義的變量,這個函數(shù)被編譯為匯編也將只有一句代碼
// mov eax, 0

int funtion2() {
    int n = 2 + 3 * 6;
    int m = n * 10;
    return m;
}
// 有意義的變量,但因?yàn)槌A總鞑ィ仓挥幸痪浯a
// mov eax, 200

## 分支優(yōu)化

對于所有不可達(dá)的分支也會直接被裁剪。

if(false) {
    printf("you can't find me");
}

在書中還有更多優(yōu)化示例,這里不做過多列舉,其根本就是以上幾種優(yōu)化方式,無意義的代碼將被刪除,冗余的代碼將會被精簡,照著這種思路想就對了。得益于編譯器的強(qiáng)大,使得再爛的代碼也能保持高效。



數(shù)學(xué)計算上對算法的優(yōu)化

我將會穿插使用 x86 和 arm 匯編,主要指令都大差不差,理解意義即可。

加法

加法沒有任何優(yōu)化空間,一個 add 指令所需的 cpu 周期本就很短,除了上述的常量折疊外,一般不會對其進(jìn)行改動。

減法

理論上加法和減法的指令周期是一致的,也不排除有些編譯器會將減數(shù)轉(zhuǎn)成補(bǔ)碼進(jìn)行相加,遇到補(bǔ)碼也能一眼看出來,直接就可以認(rèn)定這條指令為減法。

乘法

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4779

    瀏覽量

    68521
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1623

    瀏覽量

    49108
  • Andorid
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    6989
收藏 人收藏

    評論

    相關(guān)推薦

    如何編寫有利于編譯器優(yōu)化代碼

    對于嵌入式系統(tǒng),最終代碼的體積和效率取決于由編譯器生成的可執(zhí)行代碼,而非開發(fā)人員編寫的源代碼;但是源代碼
    發(fā)表于 11-09 10:31 ?1406次閱讀
    如何編寫有利于<b class='flag-5'>編譯器</b><b class='flag-5'>優(yōu)化</b>的<b class='flag-5'>代碼</b>

    如何編寫有利于編譯器優(yōu)化代碼

    本篇文章將以國際知名編譯器廠商IAR Systems的編譯器為例,來解答開發(fā)人員在實(shí)際工作中常常遇到的問題,工程師朋友們可以在IAR編譯器進(jìn)行實(shí)踐驗(yàn)證。
    發(fā)表于 08-01 09:43 ?485次閱讀
    如何編寫有利于<b class='flag-5'>編譯器</b><b class='flag-5'>優(yōu)化</b>的<b class='flag-5'>代碼</b>

    如何編寫有利于編譯器優(yōu)化代碼

    多種方式訪問一個變量,這種情況就會被稱為別名,而別名使代碼更難優(yōu)化?!”M管程序員知道向 buf 所指向的緩存區(qū)進(jìn)行寫操作不會改變這個buf變量本身,但編譯器還是不得不做最壞的打算,在循
    發(fā)表于 11-21 08:00

    如何編寫有利于編譯器優(yōu)化代碼

    多種方式訪問一個變量,這種情況就會被稱為別名,而別名使代碼更難優(yōu)化?!”M管程序員知道向 buf 所指向的緩存區(qū)進(jìn)行寫操作不會改變這個buf變量本身,但編譯器還是不得不做最壞的打算,在循
    發(fā)表于 04-11 10:17

    SIMD計算機(jī)的優(yōu)化編譯器設(shè)計

    利用處理的相關(guān)資源,提高編譯器優(yōu)化性能和增強(qiáng)代碼可適應(yīng)性是SIMD處理優(yōu)化
    發(fā)表于 04-03 08:47 ?30次下載

    Keil C編譯器編程規(guī)則和代碼優(yōu)化

    本內(nèi)容介紹了Keil C編譯器編程規(guī)則和代碼優(yōu)化,要實(shí)用好單片機(jī)就必須清楚它的內(nèi)部結(jié)構(gòu)組織結(jié)構(gòu),無論是在芯片的選擇還是代碼的編寫
    發(fā)表于 04-20 17:37 ?315次下載
    Keil C<b class='flag-5'>編譯器</b>編程規(guī)則和<b class='flag-5'>代碼</b><b class='flag-5'>優(yōu)化</b>

    編譯器_keil的優(yōu)化選項(xiàng)問題

    keil編譯器優(yōu)化選項(xiàng)針對ARM,對STM32編譯的一些優(yōu)化的問題
    發(fā)表于 02-25 14:18 ?3次下載

    C編譯器及其優(yōu)化

    本章將幫助讀者在ARM處理編寫高效的C代碼。本章涉及的一些技術(shù)不僅適用于ARM處理,也適用于其他RISC處理。本章首先從ARM
    發(fā)表于 10-17 17:22 ?2次下載

    如何使用編譯器進(jìn)行定位優(yōu)化信息

    在本次網(wǎng)絡(luò)研討會中,我們將向您展示如何使用編譯器選項(xiàng)來定位您正在尋找的確切優(yōu)化信息以及如何使用此信息來加速你的申請。
    的頭像 發(fā)表于 11-01 06:50 ?2611次閱讀

    編譯器優(yōu)化對函數(shù)的影響

    編譯器如gcc,可以指定不同的優(yōu)化參數(shù),在某些條件下,有些函數(shù)可能會被優(yōu)化掉。
    的頭像 發(fā)表于 06-22 14:58 ?2828次閱讀
    <b class='flag-5'>編譯器</b><b class='flag-5'>優(yōu)化</b>對函數(shù)的影響

    如何編寫有利于編譯器優(yōu)化代碼

    對于嵌入式系統(tǒng),最終代碼的體積和效率取決于由編譯器生成的可執(zhí)行代碼,而非開發(fā)人員編寫的源代碼;但是源代碼
    的頭像 發(fā)表于 03-29 15:58 ?1484次閱讀
    如何編寫有利于<b class='flag-5'>編譯器</b><b class='flag-5'>優(yōu)化</b>的<b class='flag-5'>代碼</b>

    交叉編譯器安裝教程

    交叉編譯器中“交叉”的意思就是在一個架構(gòu)編譯另外一個架構(gòu)的代碼,相當(dāng)于兩種架構(gòu)“交叉”起來了。Ubuntu 自帶的 gcc 編譯器是針對
    的頭像 發(fā)表于 09-29 09:12 ?3501次閱讀

    編譯器如何對代碼進(jìn)行優(yōu)化(下)

    在學(xué)習(xí) Andorid 逆向的過程中,發(fā)現(xiàn)無論是哪種編譯器,生成哪個平臺的代碼,其優(yōu)化思路在本質(zhì)如出一轍,在 Windwos 平臺所使用的技巧,在安卓平臺仍然適用,不外乎乘法除法計算
    的頭像 發(fā)表于 02-01 16:25 ?840次閱讀
    <b class='flag-5'>編譯器</b>如何對<b class='flag-5'>代碼</b><b class='flag-5'>進(jìn)行</b><b class='flag-5'>優(yōu)化</b>(下)

    編譯器優(yōu)化選項(xiàng)

    一個程序首先要保證正確性,在保證正確性的基礎(chǔ),性能也是一個重要的考量。要編寫高性能的程序,第一,必須選擇合適的算法和數(shù)據(jù)結(jié)構(gòu);第二,應(yīng)該編寫編譯器能夠有效優(yōu)化以轉(zhuǎn)換成高效可執(zhí)行代碼
    的頭像 發(fā)表于 11-24 15:37 ?891次閱讀
    <b class='flag-5'>編譯器</b>的<b class='flag-5'>優(yōu)化</b>選項(xiàng)

    Keil編譯器優(yōu)化方法

    我們都知道,代碼是可以通過編譯器優(yōu)化的,有的時候,為了提高運(yùn)行速度或者減少代碼尺寸,會開啟優(yōu)化選項(xiàng)。
    的頭像 發(fā)表于 10-23 16:35 ?504次閱讀
    Keil<b class='flag-5'>編譯器</b><b class='flag-5'>優(yōu)化</b>方法
    RM新时代网站-首页