<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # 程序編譯鏈接原理 **預處理** ~~~ .c -> .i gcc -E hello.c -o hello.i ~~~ 展開頭文件宏替換 **編譯** ~~~ .i / .c -> .s gcc -S hello.i -o hello.s ~~~ c的源代碼變成匯編 **匯編** ~~~ .s -> .o gcc -c hello.s -o hello.o ~~~ 匯編變為二進制文件 **鏈接** ~~~ .o -> 可執行程序app gcc hello.o -o app ~~~ 二進制文件變為可執行文件 # 編譯 ![](https://box.kancloud.cn/ff8807f0bb796ccda4788ce370e164d6_1348x436.jpg) linux下用ldd 可執行文件名 看一個可執行文件依賴哪些庫 window下可以用Dependency這個工具來看一個可執行文件依賴哪些庫 ![](https://box.kancloud.cn/b915cb9e79ce4ac597903ea2f1c731c5_834x383.png) ![](https://box.kancloud.cn/df03fb502c42153ad42581e662e34029_740x198.png) 1. 預處理:宏文件展開,頭文件展開,條件編譯等,同時將代碼中的注釋刪除,這里并不會檢查語法 2. 編譯: 檢查語法,將預處理后文件編譯生成匯編文件 3. 匯編: 將匯編文件生成目標文件(二進制文件) 4. 鏈接: C語言寫的程序是需要依賴各種庫的,所以編譯之后還需要把庫鏈接到最終可執行程序中去 ~~~ 預處理: gcc -E hello.c -o hello.i 編譯: gcc -S hello.i -o hello.s 匯編: gcc -c hello.s -o hello.o 鏈接: gcc hello.o -o hello_elf ~~~ | 選項 | 含義 | | --- | --- | | -E | 只進行預處理 | | -S(大寫) | 只進行預處理和編譯 | | -c(小寫) | 只進行預處理,編譯和匯編 | | -o file | 指定生成的輸出文件名為file | 在 Visual Studio 中,不用進行任何設置就可以在工程目錄下看到 demo.asm 文件 # 預處理 預處理過程主要是處理那些源文件和頭文件中以`#`開頭的命令,比如?#include、#define、#ifdef?等。預處理的規則一般如下: * 將所有的`#define`刪除,并展開所有的宏定義。 * 處理所有條件編譯命令,比如?#if、#ifdef、#elif、#else、#endif?等。 * 處理`#include`命令,將被包含文件的內容插入到該命令所在的位置,這與復制粘貼的效果一樣。注意,這個過程是遞歸進行的,也就是說被包含的文件可能還會包含其他的文件。 * 刪除所有的注釋`//`和`/* ... */`。 * 添加行號和文件名標識,便于在調試和出錯時給出具體的代碼位置。 * 保留所有的`#pragma`命令,因為編譯器需要使用它們。 預處理的結果是生成`.i`文件。`.i`文件也是包含C語言代碼的源文件,只不過所有的宏已經被展開,所有包含的文件已經被插入到當前文件中。當你無法判斷宏定義是否正確,或者文件包含是否有效時,可以查看`.i`文件來確定問題。 在 GCC 中,可以通過下面的命令生成`.i`文件: $gcc -E demo.c -o demo.i `-E`表示只進行預編譯 在 Visual Studio 中,在當前工程的屬性面板中將“預處理到文件”設置為“是”,如下圖所示: ![](https://box.kancloud.cn/2b0714b177b016679c3b4d57313aa307_701x504.png) 然后點擊“運行(Run)”或者“構建(Build)”按鈕,就能在當前工程目錄中看到 demo.i # 匯編(Assembly) 匯編的過程就是將匯編代碼轉換成可以執行的機器指令。大部分匯編語句對應一條機器指令,有的匯編語句對應多條機器指令 匯編過程相對于編譯來說比較簡單,沒有復雜的語法,也沒有語義,也不需要做指令優化,只是根據匯編語句和機器指令的對照表一一翻譯就可以了。 匯編的結果是產生目標文件,在 GCC 下的后綴為`.o`,在 Visual Studio 下的后綴為`.obj` # 鏈接(Linking) 目標文件已經是二進制文件,**與可執行文件的組織形式類似,只是有些函數和全局變量的地址還未找到,程序不能執行**。鏈接的作用就是找到這些目標地址,將所有的目標文件組織成一個可以執行的二進制文件。 預處理和匯編的過程都比較簡單,有了上面的介紹,相信大家很容易理解。 編譯的過程最為復雜,可以細分為詞法分析、語法分析、語義分析和指令優化,這里涉及到諸多算法以及正則表達式 而目標文件的結構、可執行文件的結構、鏈接的過程是我們要重點研究的,它能夠讓我們明白多文件編程以及模塊化開發的原理,這是大型項目開發的基石。 最后需要說明的是:匯編的過程非常簡單,僅僅是查表翻譯,我們通常把它作為編譯過程的一部分,不再單獨提及。這樣,源文件經過預處理、編譯和鏈接就生成了可執行文件
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看